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)
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)
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__)
.
@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.
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.
@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')
.
+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é).
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])
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ù 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.
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.
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.
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, "a demandé le 11 nov. '10 à 9h32"