Comment puis-je obtenir le chemin du fichier courant exécuté en Python?
cela peut sembler comme une question de débutant, mais il n'est pas. Certaines approches communes 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 utilisez un autre script Python dans un autre répertoire, et cela peut arriver dans la vie réelle.
__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'attribut__file__
, mais il y a un workaround - quand vous fuyez le ralenti avec
execute()
il n'y a pas__file__
attribut - OS X 10.6 où j'obtiens
NameError: global name '__file__' is not defined
questions connexes avec réponses incomplètes:
- Python - Trouver le Chemin du Fichier en Cours d'Exécution
- le chemin vers le fichier courant dépend de la façon dont j'exécute le programme
- Comment connaître le chemin d'accès de l'exécution d'un script en Python?
- Changer de répertoire pour le répertoire d'un script Python
je suis à la recherche pour une solution générique , une qui fonctionnerait dans tous les cas d'utilisation ci-dessus.
mise à Jour
voici le résultat d'un test case:
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. 1519640920"
#! /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
#! /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")
#! /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
C:.
| a.py
---subdir
b.py
10 réponses
vous ne pouvez pas déterminer directement l'emplacement du script principal exécuté. Après tout, parfois le script ne venait pas du tout d'un fichier. Par exemple, il peut provenir de l'interpréteur interactif ou du code généré dynamiquement stocké uniquement en mémoire.
cependant, vous pouvez déterminer de manière fiable l'emplacement d'un module, puisque les modules sont toujours chargés à partir d'un fichier. Si vous créez un module avec le code suivant et le mettez dans le même répertoire que votre principal script, puis le script principal peut importer le module et l'utiliser pour localiser lui-même.
some_path/module_locator.py:
def we_are_frozen():
# All of the modules are built-in to the interpreter, e.g., by py2exe
return hasattr(sys, "frozen")
def module_path():
encoding = sys.getfilesystemencoding()
if we_are_frozen():
return os.path.dirname(unicode(sys.executable, encoding))
return os.path.dirname(unicode(__file__, encoding))
some_path/main.py:
import module_locator
my_path = module_locator.module_path()
si vous avez plusieurs scripts principaux dans différents répertoires, vous pouvez avoir besoin de plus d'une copie de module_locator.
bien sûr, si votre script principal est chargé par un autre outil qui ne vous permet pas d'importer des modules qui sont co-situés avec ton scénario, alors tu n'as pas de chance. Dans de tels cas, l'information que vous recherchez n'existe tout simplement nulle part dans votre programme. Votre meilleur pari serait de fichier d'un bug avec les auteurs de l'outil.
D'abord, vous devez importer de inspect
et os
from inspect import getsourcefile
from os.path import abspath
ensuite, où que vous vouliez trouver le fichier source à partir de vous, utilisez
abspath(getsourcefile(lambda:0))
je rencontrais un problème similaire, et je pense que cela pourrait résoudre le problème:
def module_path(local_function):
''' returns the module path without the use of __file__. Requires a function defined
locally in the module.
from http://stackoverflow.com/questions/729583/getting-file-path-of-imported-module'''
return os.path.abspath(inspect.getsourcefile(local_function))
il fonctionne pour les scripts réguliers et In idle. Tout ce que je peux dire, c'est de l'essayer pour les autres!
mon usage typique:
from toolbox import module_path
def main():
pass # Do stuff
global __modpath__
__modpath__ = module_path(main)
Maintenant, j'utilise __modpath__ au lieu de __file__.
la réponse courte est que il n'y a pas de façon garantie d'obtenir l'information que vous voulez , cependant il ya des heuristiques qui fonctionnent presque toujours dans la pratique. Vous pouvez regarder Comment trouver l'emplacement de l'exécutable en C? . Il discute du problème d'un point de vue C, mais les solutions proposées sont facilement transcrites en Python.
cette solution est robuste même dans les exécutables
import inspect, os.path
filename = inspect.getframeinfo(inspect.currentframe()).filename
path = os.path.dirname(os.path.abspath(filename))
voir ma réponse à la question importation de modules à partir du dossier parent pour des informations connexes, y compris pourquoi ma réponse n'utilise pas la variable __file__
non fiable. Cette solution simple doit être compatible avec différents systèmes d'exploitation car les modules os
et inspect
font partie de Python.
tout d'abord, vous devez importer des pièces de la inspecter et os modules.
from inspect import getsourcefile
from os.path import abspath
ensuite, utilisez la ligne suivante partout où vous en avez besoin dans votre code Python:
abspath(getsourcefile(lambda:0))
Comment cela fonctionne:
du module intégré os
(description ci-dessous), l'outil abspath
est importé.
Routines OSpour Mac, NT, ou Posix selon le système sur lequel nous sommes.
alors getsourcefile
(description ci-dessous) est importé du module intégré inspect
.
obtenez des informations utiles à partir d'objets Python vivants.
-
abspath(path)
retourne la version complète/absolue d'un chemin de fichier -
getsourcefile(lambda:0)
obtient d'une manière ou d'une autre le fichier source interne de l'objet de la fonction lambda, retourne donc'<pyshell#nn>'
dans le shell Python ou renvoie le chemin du fichier de la Code Python en cours d'exécution.
en utilisant abspath
sur le résultat de getsourcefile(lambda:0)
devrait s'assurer que le chemin de fichier généré est le chemin de fichier complet du fichier Python.
Cette solution expliquée était à l'origine basée sur le code de la réponse à Comment puis-je obtenir le chemin du fichier courant exécuté en Python? .
cela devrait faire l'affaire de manière transversale (tant que vous n'utilisez pas l'interpréteur ou quelque chose du genre):
import os, sys
non_symbolic=os.path.realpath(sys.argv[0])
program_filepath=os.path.join(sys.path[0], os.path.basename(non_symbolic))
sys.path[0]
est le répertoire dans lequel se trouve votre script d'appel (le premier endroit où il cherche des modules à utiliser par ce script). Nous pouvons prendre le nom du fichier lui-même, à la fin de sys.argv[0]
(qui est ce que j'ai fait avec os.path.basename
). os.path.join
les rassemble de façon transversale. os.path.realpath
s'assure juste si nous recevons des liens symboliques avec des noms différents que le script lui-même que nous pouvons toujours obtenir le vrai nom du script.
Je n'ai pas de Mac; donc, je n'ai pas testé cela sur un seul. S'il vous plaît laissez-moi savoir si cela fonctionne, il semble qu'il devrait. J'ai testé cela sous Linux (Xubuntu) avec Python 3.4. Notez que de nombreuses solutions pour ce problème ne fonctionnent pas sur Macs (puisque j'ai entendu dire que __file__
n'est pas présent sur Macs).
Notez que si votre script est symbolique link, il vous donnera le chemin du fichier auquel il renvoie (et non le chemin du lien symbolique).
vous pouvez utiliser Path
à partir du pathlib
module:
from pathlib import Path
# ...
Path(__file__)
Vous pouvez utiliser l'appel à parent
pour aller plus loin dans le chemin:
Path(__file__).parent
vous avez simplement appelé:
path = os.path.abspath(os.path.dirname(sys.argv[0]))
au lieu de:
path = os.path.dirname(os.path.abspath(sys.argv[0]))
abspath()
vous donne le chemin absolu de sys.argv[0]
(le nom du fichier dans lequel se trouve votre code) et dirname()
renvoie le chemin du répertoire sans le nom du fichier.
il suffit D'ajouter ce qui suit:
from sys import *
path_to_current_file = sys.argv[0]
print(path_to_current_file)
ou:
from sys import *
print(sys.argv[0])