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)
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)
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__)
.
@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.
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.
@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')
.
+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é).
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])
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 :
Une liste de différentes approches qui renvoient le chemin complet vers le script en cours d'exécution.
Une mise en garde concernant la gestion des chemins relatifs.
Une recommandation concernant la gestion des liens symboliques.
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.
__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
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.
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.
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.
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.
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.
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.
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.
1 votes
Python 2 est obsolète. Utilisez print(var) à la place.
1 votes
Elia Iliashenko, "demandé le 11 nov '10 à 9:32"