512 votes

Obtenir le nom du script actuel en Python

J'essaie d'obtenir le nom du script Python qui est en cours d'exécution.

J'ai un script appelé foo.py et j'aimerais faire quelque chose comme ceci afin d'obtenir le nom du script :

print(Scriptname)

1 votes

Python 2 est obsolète. Utilisez print(var) à la place.

1 votes

Elia Iliashenko, "demandé le 11 nov '10 à 9:32"

765voto

Sven Marnach Points 133943

Vous pouvez utiliser __file__ pour obtenir le nom du fichier courant. Lorsqu'il est utilisé dans le module principal, c'est le nom du script qui a été invoqué à l'origine.

Si vous voulez omettre la partie répertoire (qui pourrait être présente), vous pouvez utiliser os.path.basename(__file__) .

24 votes

Python 3.2 : " Exception NameError: NameError("global name '__file__' is not defined",) "

29 votes

@sdaau : __file__ n'est pas défini dans l'interpréteur interactif, car il n'y a pas de sens. Elle est définie par l'implémentation de l'importation, donc si vous utilisez un mécanisme d'importation non standard, elle peut aussi être non définie.

8 votes

Au moins pour Python 2.7, je crois qu'une fonction import os est nécessaire pour que cela fonctionne. J'ajouterais ceci dans la réponse.

177voto

Chris Morgan Points 22285
import sys
print(sys.argv[0])

Ceci imprimera foo.py pour python foo.py , dir/foo.py pour python dir/foo.py etc. C'est le premier argument pour python . (Notez qu'après py2exe, ce serait foo.exe .)

36 votes

@DenisMalinovsky : définissez "ne fonctionnera pas". Si vous appelez python linkfile.py , donde linkfile.py est un lien symbolique vers realfile.py , sys.argv[0] sera 'linkfile.py' ce qui n'est peut-être pas ce que vous voulez, mais c'est en tout cas ce que je veux. s'attendre à . __file__ est le même : il sera linkfile.py . Si vous voulez trouver 'realfile.py' de 'linkfile.py' essayez. os.path.realpath('linkfile.py') .

8 votes

+1 parce que c'est (a) un peu plus propre et (b) fonctionnera toujours dans le module (où l'option fichier serait le fichier du module, et non celui qui est exécuté).

1 votes

Cette réponse est intéressante car elle fonctionne également dans IDLE. A titre d'information, pour obtenir uniquement le nom du fichier, vous pouvez écrire os.path.basename(sys.argv[0])

115voto

Yoel Points 5577

Par souci d'exhaustivité, j'ai pensé qu'il serait utile de résumer les différents résultats possibles et de fournir des références sur le comportement exact de chacun.

La réponse est composée de quatre sections :

  1. Une liste de différentes approches qui renvoient le chemin complet vers le script en cours d'exécution.

  2. Une mise en garde concernant la gestion des chemins relatifs.

  3. Une recommandation concernant la gestion des liens symboliques.

  4. Un compte rendu de quelques méthodes qui pourraient être utilisées pour extraire le nom réel du fichier, avec ou sans son suffixe, à partir du chemin complet du fichier.


Extraction du chemin complet du fichier

  • __file__ est le fichier actuellement en cours d'exécution, comme indiqué dans le fichier documentation officielle :

    __file__ est le nom du chemin du fichier à partir duquel le module a été chargé, s'il a été chargé à partir d'un fichier. L'adresse __file__ peut être absent pour certains types de modules, tels que les modules C qui sont liés statiquement à l'interpréteur ; pour les modules d'extension chargés dynamiquement à partir d'une bibliothèque partagée, il s'agit du nom de chemin du fichier de la bibliothèque partagée.

    De Python3.4 à partir de, par numéro 18416 , __file__ est toujours un chemin absolu, à moins que le fichier en cours d'exécution ne soit un script qui a été exécuté directement (pas via l'interpréteur avec la commande -m option de ligne de commande) en utilisant un chemin relatif.

  • __main__.__file__ (nécessite d'importer __main__ ) accède simplement à l'objet susmentionné __file__ de l'attribut module principal , par exemple du script qui a été invoqué depuis la ligne de commande.

    De Python3.9 à partir de, par numéro 20443 le __file__ de l'attribut __main__ est devenu un chemin absolu, plutôt qu'un chemin relatif.

  • sys.argv[0] (nécessite d'importer sys ) est le nom du script qui a été invoqué à partir de la ligne de commande, et peut être un chemin absolu, comme détaillé dans le fichier documentation officielle :

    argv[0] est le nom du script (le fait que ce soit un chemin complet ou non dépend du système d'exploitation). Si la commande a été exécutée en utilisant l'option -c option de ligne de commande pour l'interpréteur, argv[0] est défini comme la chaîne de caractères '-c' . Si aucun nom de script n'a été passé à l'interpréteur Python, argv[0] est la chaîne vide.

    Comme mentionné dans une autre réponse à cette question , Python des scripts qui ont été convertis en programmes exécutables autonomes via des outils tels que py2exe o PyInstaller pourrait ne pas afficher le résultat souhaité lorsqu'on utilise cette approche (c'est à dire sys.argv[0] contiendrait le nom de l'exécutable plutôt que le nom du fichier principal. Python dans cet exécutable).

  • Si aucune des options susmentionnées ne semble fonctionner, probablement en raison d'un processus d'exécution atypique ou d'une opération d'importation irrégulière, la fonction inspecter module pourrait s'avérer utile. En particulier, l'invocation de inspect.stack()[-1][1] devrait fonctionner, bien qu'il soulève une exception lorsqu'il est exécuté dans une implémentation sans Python cadre de la pile.

  • De Python3.6 et comme détaillé dans une autre réponse à cette question il est possible d'installer une bibliothèque open source externe, lib_programme qui est conçu pour apporter une solution complète à ce problème.

    Cette bibliothèque itère à travers toutes les approches listées ci-dessus jusqu'à ce qu'un chemin valide soit retourné. Si toutes ces approches échouent, elle lève une exception. Elle tente également de remédier à divers pièges, tels que les invocations par le biais de la fonction pytest ou le pydoc module.

    import lib_programname
    # this returns the fully resolved path to the launched python program
    path_to_program = lib_programname.get_path_executed_script()  # type: pathlib.Path

Gestion des chemins relatifs

Lorsqu'on a affaire à une approche qui renvoie un chemin relatif, il peut être tentant d'invoquer diverses fonctions de manipulation de chemin, telles que os.path.abspath(...) o os.path.realpath(...) afin d'extraire le chemin complet ou réel.

Cependant, ces méthodes s'appuient sur le chemin actuel afin de dériver le chemin complet. Ainsi, si un programme modifie d'abord le répertoire de travail actuel, par exemple par le biais de os.chdir(...) et n'invoque qu'ensuite ces méthodes, elles renverraient un chemin incorrect.


Gestion des liens symboliques

Si le script actuel est un lien symbolique, alors tout ce qui précède renverrait le chemin du lien symbolique plutôt que le chemin du fichier réel, et os.path.realpath(...) doit être invoqué afin d'extraire ce dernier.


D'autres manipulations permettant d'extraire le nom réel du fichier

os.path.basename(...) peut être invoqué sur n'importe lequel des éléments ci-dessus afin d'extraire le nom du fichier et le nom de l'utilisateur. os.path.splitext(...) peut être invoqué sur le nom de fichier réel afin de tronquer son suffixe, comme dans os.path.splitext(os.path.basename(...)) .

De Python 3.4 à partir de, par PEP 428 le PurePath classe de la pathlib module peut également être utilisé sur n'importe lequel des éléments ci-dessus. En particulier, pathlib.PurePath(...).name extrait le nom réel du fichier et pathlib.PurePath(...).stem extrait le nom réel du fichier sans son suffixe.

67voto

Ambroz Bizjak Points 3398

Notez que __file__ donnera le fichier où réside ce code, qui peut être importé et différent du fichier principal en cours d'interprétation. Pour obtenir le fichier principal, la fonction spéciale __main__ peut être utilisé :

import __main__ as main
print(main.__file__)

Notez que __main__.__file__ fonctionne dans Python 2.7 mais pas dans 3.2, utilisez donc la syntaxe import-as comme ci-dessus pour le rendre portable.

0 votes

Cela fonctionne dans de nombreux cas, mais pas lorsque j'utilise la fonction rPython paquet de R langue. Il doit s'agir d'un cas exceptionnel qui est tout simplement trop difficile à gérer.

0 votes

En effet, le paquet rPython intègre l'interpréteur python, ce qui signifie qu'il n'y a pas de fichier 'principal' comme c'est le cas lorsque python fonctionne seul (vous trouverez le même comportement chaque fois que python est intégré). Il importe __main__ en interne, pour le passage de variables entre R y python Il serait donc relativement facile de le mettre en place. __main__.__file__ avant d'appeler quoi que ce soit d'autre, mais je ne suis même pas sûr de ce qui serait une valeur appropriée dans ce cas.

51voto

Manoj Sahu Points 1437

Les réponses ci-dessus sont bonnes. Mais j'ai trouvé cette méthode plus efficace en utilisant les résultats ci-dessus.
Il en résulte un nom de fichier script réel et non un chemin.

import sys    
import os    
file_name =  os.path.basename(sys.argv[0])

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X