512 votes

Obtenir le nom du script actuel en Python

Je suis en train d'essayer d'obtenir le nom du script Python qui est actuellement en cours d'exécution.

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

print(Nom_du_script)

1 votes

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

1 votes

Elia Iliashenko, "a demandé le 11 nov. '10 à 9h32"

765voto

Sven Marnach Points 133943

Vous pouvez utiliser __file__ pour obtenir le nom du fichier actuel. Lorsqu'il est utilisé dans le module principal, il s'agit du nom du script qui a été initialement invoqué.

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

24 votes

Python 3.2: "Exception NameError: NameError("nom de variable non défini '__file__'",)"

29 votes

@sdaau : __file__ n'est pas défini dans l'interpréteur interactif, car il est sans signification là. Il est défini par l'implémentation de l'importation, donc si vous utilisez un mécanisme d'importation non standard, il pourrait également être non défini.

8 votes

Au moins pour Python 2.7, je crois qu'un import os est requis pour que cela fonctionne. Je le rajouterais dans la réponse.

177voto

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

Cela affichera foo.py pour python foo.py, dir/foo.py pour python dir/foo.py, etc. C'est le premier argument de python. (Remarquez qu'après py2exe, ce serait foo.exe.)

36 votes

@DenisMalinovsky : définissez "ne fonctionne pas". Si vous appelez python linkfile.py, où linkfile.py est un lien symbolique vers realfile.py, sys.argv[0] sera 'linkfile.py', ce qui peut ou non être ce que vous voulez ; c'est certainement ce que je attends. __file__ est le même : il sera linkfile.py. Si vous voulez trouver 'realfile.py' à partir de 'linkfile.py', essayez os.path.realpath('linkfile.py').

8 votes

+1 car c'est (a) un peu plus propre et (b) continuera de fonctionner dans le module (où la variable file serait le fichier du module, pas celui exécuté).

1 votes

Cette réponse est gentille car elle fonctionne également dans IDLE. À noter, 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ù se trouve ce code, qui peut être importé et différent du fichier principal en cours d'interprétation. Pour obtenir le fichier principal, le module spécial __main__ peut être utilisé :

import __main__ as main
print(main.__file__)

Notez que __main__.__file__ fonctionne en Python 2.7 mais pas en 3.2, donc utilisez la syntaxe d'importation comme ci-dessus pour le rendre portable.

0 votes

Cela fonctionne dans de nombreux cas mais pas lorsque j'utilise le package rPython du langage R. Cela doit être un cas exceptionnel qui est tout simplement trop difficile à gérer.

0 votes

En effet, le package 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 est exécuté seul (vous trouverez le même comportement à chaque fois que python est intégré). Il importe __main__ de manière interne, pour une utilisation dans le passage de variables entre R et python, il serait donc relativement facile de le faire définir __main__.__file__ avant d'appeler autre chose, mais je ne suis même pas sûr de quelle 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.
Cela donne le nom réel du fichier de script, pas un chemin.

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

1 votes

J'aime aussi séparer l'extension, donc j'utilise: os.path.splitext(os.path.basename(sys.argv[0]))[0]

0 votes

Pour moi quelques années plus tard avec Python 3.8 cela affiche ipykernel_launcher.py et non le nom du fichier.

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