J'essaie d'obtenir le nom du script Python en cours d'exécution.
J'ai un script appelé foo.py
et j'aimerais faire quelque chose comme ça afin d'obtenir le nom du script:
print Scriptname
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 appelé.
Si vous souhaitez omettre la partie répertoire (qui peut être présente), vous pouvez utiliser os.path.basename(__file__)
.
Exception NameError: NameError("global name '__file__' is not defined",)
"__file__
n'est pas défini dans l'interpréteur interactif, car il n'a pas de sens là-bas. Il est défini par l'implémentation d'importation, donc si vous utilisez un mécanisme d'importation non standard, il peut également ne pas être défini.import os
est requis pour que cela fonctionne. J'ajouterais ceci dans la réponse.import os
etimport os.path
sont complètement équivalents.Cela s'imprimera
foo.py
pourpython foo.py
,dir/foo.py
pourpython dir/foo.py
, etc. C'est le premier argument depython
. (Notez qu'après py2exe, ce serait le casfoo.exe
.)la source
python linkfile.py
, oùlinkfile.py
est un lien symbolique versrealfile.py
,sys.argv[0]
sera'linkfile.py'
, qui peut ou non être ce que vous voulez; c'est certainement ce que j'attends .__file__
c'est pareil: ça le seralinkfile.py
. Si vous souhaitez rechercher à'realfile.py'
partir de'linkfile.py'
, essayezos.path.realpath('linkfile.py')
.__file__
plutôt.Dans un 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 pour le comportement exact de chacun:
__file__
est le fichier en cours d'exécution, comme détaillé dans la documentation officielle :À partir de Python3.4 , par problème 18416 ,
__file__
est toujours un chemin absolu, sauf si le fichier en cours d'exécution est un script qui a été exécuté directement (pas via l'interpréteur avec l'-m
option de ligne de commande) en utilisant un chemin relatif.__main__.__file__
(nécessite l'importation__main__
) accède simplement à l'__file__
attribut susmentionné du module principal , par exemple du script qui a été appelé à partir de la ligne de commande.sys.argv[0]
(nécessite l'importationsys
) est le nom du script qui a été appelé à partir de la ligne de commande, et peut être un chemin absolu, comme détaillé dans la documentation officielle :Comme mentionné dans une autre réponse à cette question , les scripts Python qui ont été convertis en programmes exécutables autonomes via des outils tels que py2exe ou PyInstaller peuvent ne pas afficher le résultat souhaité lors de l'utilisation de cette approche (c'est
sys.argv[0]
-à- dire contenir le nom de l'exécutable plutôt que le nom du fichier Python principal dans cet exécutable).Si aucune des options susmentionnées ne semble fonctionner, probablement en raison d'une opération d'importation irrégulière, le module d'inspection peut s'avérer utile. En particulier, invoquer
inspect.getfile(...)
surinspect.currentframe()
pourrait fonctionner, bien que ce dernier revienneNone
lors de l'exécution dans une implémentation sans cadre de pile Python .Gérer les liens symboliques
Si le script actuel est un lien symbolique, alors tout ce qui précède retournerait le chemin du lien symbolique plutôt que le chemin du fichier réel et
os.path.realpath(...)
devrait être invoqué pour extraire ce dernier.Manipulations supplémentaires qui extraient le nom de fichier réel
os.path.basename(...)
peut être invoqué sur l'un des éléments ci-dessus afin d'extraire le nom de fichier réel etos.path.splitext(...)
peut être invoqué sur le nom de fichier réel afin de tronquer son suffixe, comme dansos.path.splitext(os.path.basename(...))
.À partir de Python 3.4 , conformément au PEP 428 , la
PurePath
classe dupathlib
module peut également être utilisée sur n'importe lequel des éléments ci-dessus. Plus précisément,pathlib.PurePath(...).name
extrait le nom de fichier réel etpathlib.PurePath(...).stem
extrait le nom de fichier réel sans son suffixe.la source
Notez que
__file__
cela 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, le module spécial __main__ peut être utilisé:Notez que cela
__main__.__file__
fonctionne dans Python 2.7 mais pas dans 3.2, utilisez donc la syntaxe import-as comme ci-dessus pour la rendre portable.la source
rPython
package à partir de laR
langue. Ce doit être un cas exceptionnel qui est tout simplement trop difficile à gérer.__main__
interne, pour être utilisé pour passer des variables entreR
etpython
, il serait donc relativement facile de le définir__main__.__file__
avant d'appeler autre chose, mais je ne suis même pas sûr de ce que serait une valeur appropriée dans ce cas.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 que le nom de fichier de script réel n'est pas un chemin.
la source
Pour les versions modernes de Python (3.4+),
Path(__file__).name
devrait être plus idiomatique. VousPath(__file__).stem
donne également le nom du script sans l'.py
extension.la source
from pathlib import Path
abord.pathlib
été introduit dans Python 3.4, il devrait donc fonctionner à partir de Python 3.4.Essaye ça:
la source
Remarque: Si vous utilisez Python 3+, vous devez utiliser la fonction print () à la place
En supposant que le nom de fichier est
foo.py
, l'extrait ci-dessousou
Comme pour les autres extensions avec plus de caractères, par exemple le nom de fichier
foo.pypy
Si vous souhaitez extraire d'un chemin absolu
affichera
foo
la source
__file__
etsys.argv[0]
, voir stackoverflow.com/questions/5851588/…Le premier argument dans sys sera le nom du fichier actuel, donc cela fonctionnera
la source
Si vous effectuez une importation inhabituelle (par exemple, c'est un fichier d'options), essayez:
Notez que cela renverra le chemin absolu du fichier.
la source
nous pouvons essayer ceci pour obtenir le nom du script actuel sans extension.
la source
Étant donné que l'OP a demandé le nom du fichier de script actuel, je préférerais
la source
toutes ces réponses sont excellentes, mais ont quelques problèmes que vous pourriez ne pas voir au premier coup d'œil.
permet de définir ce que nous voulons - nous voulons le nom du script qui a été exécuté, pas le nom du module actuel -
__file__
ne fonctionnera donc que s'il est utilisé dans le script exécuté, pas dans un module importé.sys.argv
est également discutable - et si votre programme était appelé par pytest? ou coureur pydoc? ou si elle a été appelée par uwsgi?et - il y a une troisième méthode pour obtenir le nom du script, je n'ai pas vu dans les réponses - Vous pouvez inspecter la pile.
Un autre problème est que vous (ou un autre programme) pouvez altérer
sys.argv
et__main__.__file__
- il peut être présent, il se peut que ce ne soit pas le cas. Il peut être valide ou non. Vous pouvez au moins vérifier si le script (le résultat souhaité) existe!ma bibliothèque bitranox / lib_programname sur github fait exactement cela:
__main__
est présent__main__.__file__
est présent__main__.__file__
un résultat valide (ce script existe-t-il?)par là, ma solution fonctionne à ce jour avec
setup.py test
,uwsgi
,pytest
,pycharm pytest
,pycharm docrunner (doctest)
,dreampie
,eclipse
il y a aussi un bel article de blog sur ce problème de Dough Hellman, "Déterminer le nom d'un processus à partir de Python"
la source
Ma solution rapide et sale:
la source
os.path
pour diviser les noms de fichiersos.path.abspath(__file__)
vous donnera un chemin absolu (égalementrelpath()
disponible).sys.argv[-1]
vous donnera un chemin relatif.la source
Depuis Python 3.5, vous pouvez simplement faire:
Voir plus ici: https://docs.python.org/3.5/library/pathlib.html#pathlib.PurePath.stem
Par exemple, j'ai un fichier sous mon répertoire utilisateur nommé
test.py
avec ceci à l'intérieur:l'exécution de ces sorties:
la source