Réponses:
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__)
.
__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
et import os.path
sont complètement équivalents.
import sys
print sys.argv[0]
Cela s'imprimera foo.py
pour python foo.py
, dir/foo.py
pour python dir/foo.py
, etc. C'est le premier argument de python
. (Notez qu'après py2exe, ce serait le cas foo.exe
.)
python linkfile.py
, où linkfile.py
est un lien symbolique vers realfile.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 sera linkfile.py
. Si vous souhaitez rechercher à 'realfile.py'
partir de 'linkfile.py'
, essayez os.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 :
__file__
est le chemin d'accès du fichier à partir duquel le module a été chargé, s'il a été chargé à partir d'un fichier. L'__file__
attribut peut être manquant 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, c'est le chemin d'accès du fichier de bibliothèque partagée.
À 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'importation sys
) 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 :
argv[0]
est le nom du script (il dépend du système d'exploitation, qu'il s'agisse ou non d'un chemin d'accès complet). Si la commande a été exécutée à l'aide de l'-c
option de ligne de commande de l'interpréteur,argv[0]
est définie sur la chaîne'-c'
. Si aucun nom de script n'a été transmis à l'interpréteur Python, ilargv[0]
s'agit de la chaîne vide.
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(...)
sur inspect.currentframe()
pourrait fonctionner, bien que ce dernier revienneNone
lors de l'exécution dans une implémentation sans cadre de pile Python .
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.
os.path.basename(...)
peut être invoqué sur l'un des éléments ci-dessus afin d'extraire le nom de fichier réel et 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(...))
.
À partir de Python 3.4 , conformément au PEP 428 , la PurePath
classe du pathlib
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 et pathlib.PurePath(...).stem
extrait le nom de fichier réel sans son suffixe.
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é:
import __main__ as main
print(main.__file__)
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.
rPython
package à partir de la R
langue. Ce doit être un cas exceptionnel qui est tout simplement trop difficile à gérer.
__main__
interne, pour être utilisé pour passer des variables entre R
et python
, 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.
import sys
import os
file_name = os.path.basename(sys.argv[0])
Pour les versions modernes de Python (3.4+), Path(__file__).name
devrait être plus idiomatique. Vous Path(__file__).stem
donne également le nom du script sans l' .py
extension.
from pathlib import Path
abord.
pathlib
été introduit dans Python 3.4, il devrait donc fonctionner à partir de Python 3.4.
En supposant que le nom de fichier est foo.py
, l'extrait ci-dessous
import sys
print sys.argv[0][:-3]
ou
import sys
print sys.argv[0][::-1][3:][::-1]
Comme pour les autres extensions avec plus de caractères, par exemple le nom de fichier foo.pypy
import sys
print sys.argv[0].split('.')[0]
Si vous souhaitez extraire d'un chemin absolu
import sys
print sys.argv[0].split('/')[-1].split('.')[0]
affichera foo
__file__
et sys.argv[0]
, voir stackoverflow.com/questions/5851588/…
Le premier argument dans sys sera le nom du fichier actuel, donc cela fonctionnera
import sys
print sys.argv[0] # will print the file name
Si vous effectuez une importation inhabituelle (par exemple, c'est un fichier d'options), essayez:
import inspect
print (inspect.getfile(inspect.currentframe()))
Notez que cela renverra le chemin absolu du fichier.
nous pouvons essayer ceci pour obtenir le nom du script actuel sans extension.
import os
script_name = os.path.splitext(os.path.basename(__file__))[0]
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"
Ma solution rapide et sale:
__file__.split('/')[-1:][0]
os.path
pour diviser les noms de fichiers
os.path.abspath(__file__)
vous donnera un chemin absolu (également relpath()
disponible).
sys.argv[-1]
vous donnera un chemin relatif.
Depuis Python 3.5, vous pouvez simplement faire:
from pathlib import Path
Path(__file__).stem
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:
from pathlib import Path
print(Path(__file__).stem)
print(__file__)
l'exécution de ces sorties:
>>> python3.6 test.py
test
test.py
Exception NameError: NameError("global name '__file__' is not defined",)
"