Cela peut sembler une question pour les débutants, mais ce n'est pas le cas. Certaines approches courantes ne fonctionnent pas dans tous les cas:
sys.argv [0]
Cela signifie utiliser path = os.path.abspath(os.path.dirname(sys.argv[0]))
, mais cela ne fonctionne pas si vous exécutez à partir d'un autre script Python dans un autre répertoire, et cela peut arriver dans la vraie vie.
__fichier__
Cela signifie utiliser path = os.path.abspath(os.path.dirname(__file__))
, mais j'ai trouvé que cela ne fonctionne pas:
py2exe
n'a pas d'__file__
attribut, mais il existe une solution de contournement- Lorsque vous exécutez à partir de IDLE
execute()
sans__file__
attribut - OS X 10.6 où j'obtiens
NameError: global name '__file__' is not defined
Questions connexes avec des réponses incomplètes:
- Python - Trouver le chemin du fichier en cours d'exécution
- Le chemin vers le fichier actuel dépend de la façon dont j'exécute le programme
- Comment connaître le chemin du script en cours d'exécution en Python?
- Changer de répertoire vers le répertoire d'un script Python
Je recherche une solution générique , qui fonctionnerait dans tous les cas d'utilisation ci-dessus.
Mettre à jour
Voici le résultat d'un testcase:
Sortie de python a.py (sous Windows)
a.py: __file__= a.py
a.py: os.getcwd()= C:\zzz
b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:\zzz
a.py
#! /usr/bin/env python
import os, sys
print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print
execfile("subdir/b.py")
subdir / b.py
#! /usr/bin/env python
import os, sys
print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print
arbre
C:.
| a.py
\---subdir
b.py
NameError: global name '__file__' is not defined
utilisant le fichier et ce n'est pas à l' intérieur du IDLE. Pensez que ce__file__
n'est défini qu'à l'intérieur des modules.__file__
n'avait rien à voir avec Unicode. Je ne sais pas pourquoi__file__
n'est pas défini mais je recherche une solution générique qui fonctionnera dans tous les cas.some_path/module_locator.py
place?Tout d'abord, vous devez importer depuis
inspect
etos
Ensuite, où que vous vouliez trouver le fichier source, utilisez simplement
la source
NameError: global name '__file__' is not defined
(une autre solution a causé cela).lambda:_
. Cela a fonctionné pour moi - je ne suis pas sûr que cela fonctionnera toujours.lambda:0
fonctionne probablement plus vite d'une quantité incommensurablement petite (ou peut-être pas si petite ... pourrait être une charge immédiate ou quelque chose d'encore plus rapide pour0
une charge globale pour_
?) On peut se demander si c'est plus propre ou plus facile à lire ou même plus intelligent / obscur.getsourcefile(lambda:0)
n'aura aucun sens et reviendra simplementNone
si vous essayez de l'exécuter à une invite interactive (puisque lelambda
ne sera dans aucun fichier source.) Si vous voulez savoir d'où vient une autre fonction ou un autre objet dans un environnement interactif,abspath(getsourcefile(thatFunctionOrObject))
sera peut -être plus utile pour vous?cette solution est robuste même dans les exécutables
la source
entry_point: console_script
, mais aucune des autres réponses.Je rencontrais un problème similaire, et je pense que cela pourrait résoudre le problème:
Cela fonctionne pour les scripts réguliers et en veille. Tout ce que je peux dire, c'est de l'essayer pour les autres!
Mon utilisation typique:
Maintenant, j'utilise __modpath__ au lieu de __file__.
la source
__modpath__
doivent donc être renommés. Vous n'avez probablement pas non plus besoin de laglobal
déclaration. Sinon +1!module_path()
. iemodule_path(lambda _: None)
qui ne dépend pas des autres contenus du script danslambda _: None
et je l'ai utilisée pendant près de deux ans, mais tout à l'heure j'ai découvert que je pouvais la condenser à justelambda:0
. Y a-t-il une raison particulière pour laquelle vous avez suggéré la forme que vous avez faite, avec un argument ignoré de_
, plutôt que sans argument du tout? Y a-t-il quelque chose de supérieurNone
préfixé avec un espace plutôt que juste0
? Ils sont tous les deux tout aussi énigmatiques, je pense, un seul compte 8 caractères tandis que l'autre compte 14 caractères.lambda _:
c'est une fonction qui prend un argument etlambda:
qui n'en prend pas. Cela n'a pas d'importance puisque la fonction n'est jamais appelée. De même, la valeur de retour utilisée n'a pas d'importance. J'imagine que j'ai choisiNone
parce qu'à l'époque, cela semblait indiquer que c'était une fonction de ne rien faire et de ne jamais être mieux appelée. L'espace devant celui-ci est facultatif et là encore uniquement pour une meilleure lisibilité (toujours essayer de suivre PEP8 est une habitude).lambda
cependant, l'utiliser pour quelque chose qu'il n'a jamais été censé faire. Si vous deviez suivre PEP8, je pense que le bon contenu seraitpass
nonNone
, mais ce n'est pas valide de mettre une déclaration dans unlambda
, donc vous devez mettre quelque chose avec une valeur. Il y a quelques éléments valides à 2 caractères que vous pouvez insérer, mais je pense que les seuls éléments valides à un seul caractère que vous pouvez insérer sont 0-9 (ou un nom de variable à caractère unique attribué en dehors dulambda
.) Je pense que le0
mieux indique le néant de 0- 9.La réponse courte est qu'il n'y a pas de moyen garanti d'obtenir les informations souhaitées , mais il existe des heuristiques qui fonctionnent presque toujours dans la pratique. Vous pourriez regarder Comment puis-je trouver l'emplacement de l'exécutable en C? . Il aborde le problème d'un point de vue C, mais les solutions proposées sont facilement transcrites en Python.
la source
Voir ma réponse à la question Importer des modules à partir du dossier parent pour des informations connexes, y compris pourquoi ma réponse n'utilise pas la
__file__
variable non fiable . Cette solution simple doit être compatible avec différents systèmes d'exploitation comme les modulesos
etinspect
faire partie de Python.Tout d' abord, vous devez parties à l'importation de l' inspectent et os modules.
Ensuite, utilisez la ligne suivante partout ailleurs dans votre code Python:
Comment ça fonctionne:
Depuis le module intégré
os
(description ci-dessous), l'abspath
outil est importé.Ensuite
getsourcefile
(description ci-dessous) est importé du module intégréinspect
.abspath(path)
renvoie la version absolue / complète d'un chemin de fichiergetsourcefile(lambda:0)
obtient en quelque sorte le fichier source interne de l'objet de la fonction lambda, donc retourne'<pyshell#nn>'
dans le shell Python ou retourne le chemin du fichier du code Python en cours d'exécution.En utilisant
abspath
le résultat de,getsourcefile(lambda:0)
vous devez vous assurer que le chemin du fichier généré est le chemin complet du fichier Python.Cette solution expliquée était à l'origine basée sur le code de la réponse à Comment obtenir le chemin du fichier actuellement exécuté en Python? .
la source
Vous avez simplement appelé:
au lieu de:
abspath()
vous donne le chemin absolu desys.argv[0]
(le nom de fichier dans lequel se trouve votre code) etdirname()
renvoie le chemin du répertoire sans le nom de fichier.la source
Cela devrait faire l'affaire de manière multiplateforme (tant que vous n'utilisez pas l'interpréteur ou quelque chose):
sys.path[0]
est le répertoire dans lequel se trouve votre script appelant (le premier endroit où il recherche les modules à utiliser par ce script). Nous pouvons prendre le nom du fichier lui-même à la fin desys.argv[0]
(ce que j'ai fait avecos.path.basename
).os.path.join
les colle simplement ensemble de manière multiplateforme.os.path.realpath
s'assure simplement que si nous obtenons des liens symboliques avec des noms différents de ceux du script lui-même, nous obtenons toujours le vrai nom du script.Je n'ai pas de Mac; donc, je ne l'ai pas testé sur un seul. S'il vous plaît laissez-moi savoir si cela fonctionne, comme il semble que cela devrait. J'ai testé cela sous Linux (Xubuntu) avec Python 3.4. Notez que de nombreuses solutions à ce problème ne fonctionnent pas sur les Mac (depuis que j'ai entendu dire que ce
__file__
n'est pas présent sur les Mac).Notez que si votre script est un lien symbolique, il vous donnera le chemin du fichier vers lequel il est lié (et non le chemin du lien symbolique).
la source
Vous pouvez utiliser à
Path
partir dupathlib
module:Vous pouvez utiliser l'appel à
parent
pour aller plus loin dans le chemin:la source
__file__
variable qui peut ne pas être fiable (n'est pas toujours le chemin complet du fichier, ne fonctionne pas sur tous les systèmes d'exploitation, etc.) comme les utilisateurs de StackOverflow l'ont souvent mentionné. Changer la réponse pour ne pas l'inclure causera moins de problèmes et sera plus compatible entre les deux. Pour plus d'informations, consultez stackoverflow.com/a/33532002/3787376 .Si le code provient d'un fichier, vous pouvez obtenir son nom complet
Vous pouvez également récupérer le nom de la fonction sous la forme
f_code.co_name
la source
Ajoutez simplement ce qui suit:
Ou:
la source
Ma solution est:
la source
la source
'__file__'
ne devrait pas être une chaîne, deuxièmement, si vous le faisiez__file__
, cela ne fonctionnerait que pour le fichier dans lequel se trouve cette ligne de code, et non pour le fichier qui est exécuté?