J'ai des scripts appelant d'autres fichiers de script, mais j'ai besoin d'obtenir le chemin du fichier en cours d'exécution dans le processus.
Par exemple, supposons que j'ai trois fichiers. Utiliser execfile :
script_1.py
les appelsscript_2.py
.- À son tour, les
script_2.py
appelsscript_3.py
.
Comment puis-je obtenir le nom et le chemin du fichier script_3.py
, à partir du code à l'intérieurscript_3.py
, sans avoir à transmettre ces informations comme arguments script_2.py
?
(L'exécution os.getcwd()
renvoie le chemin de fichier du script de démarrage d'origine et non celui du fichier en cours.)
__file__
absolu ou relatif?Réponses:
p1.py:
p2.py:
la source
inspect.getabsfile()
et cela a fonctionné pour tous les cas que j'ai essayés.os.path.realpath(__file__)
comme d'autres l'ont dit. Vous pouvez également utiliser os.path.realpath pour éliminer les liens symboliques:
la source
__file__
retourne 'script_name.py', et parfois 'script_name.pyc'. La sortie n'est donc pas stable."__file__"
entre guillemets (sous forme de chaîne) donne le répertoire à partir duquel cmd est exécuté, mais__file__
(sans guillemets donne le chemin d'accès au fichier source ... pourquoi est-ceos.path.realpath
fonction suppose que ladir
partie du chemin soit.os.path.dirname(os.path.realpath(__file__))
retourne le répertoire avec le fichier.os.path.dirname(os.path.realpath("__file__"))
renvoie cwd.os.path.dirname(os.path.realpath("here_be_dragons"))
renvoie également cwd.Mise à jour 2018-11-28:
Voici un résumé des expériences avec Python 2 et 3. Avec
main.py - exécute foo.py
foo.py - exécute lib / bar.py
lib / bar.py - imprime les expressions de chemin de fichier
Pour Python 2, il peut être plus clair de passer aux packages, vous pouvez donc l'utiliser
from lib import bar
- ajoutez simplement des__init__.py
fichiers vides aux deux dossiers.Pour Python 3,
execfile
n'existe pas - l'alternative la plus proche estexec(open(<filename>).read())
, bien que cela affecte les cadres de pile. Il est plus simple à utiliserimport foo
etimport lib.bar
- aucun__init__.py
fichier n'est nécessaire.Voir aussi Différence entre import et execfile
Réponse originale:
Voici une expérience basée sur les réponses de ce fil - avec Python 2.7.10 sous Windows.
Les piles basées sur la pile sont les seules qui semblent donner des résultats fiables. Les deux derniers ont la syntaxe la plus courte , c'est-à-dire -
Voici à ces ajouts à sys en tant que fonctions! Crédit à @Usagi et @pablog
Sur la base des trois fichiers suivants, et en exécutant main.py à partir de son dossier avec
python main.py
(également des fichiers exécutés essayés avec des chemins absolus et appelant à partir d'un dossier séparé).C: \ filepaths \ main.py:
execfile('foo.py')
C: \ filepaths \ foo.py:
execfile('lib/bar.py')
C: \ filepaths \ lib \ bar.py:
la source
Je pense que c'est plus propre:
et obtient les mêmes informations que:
Où [0] est l'image actuelle dans la pile (haut de la pile) et [1] pour le nom du fichier, augmentez pour revenir en arrière dans la pile, c.-à-d.
serait le nom de fichier du script qui a appelé l'image actuelle. De plus, l'utilisation de [-1] vous amènera au bas de la pile, le script d'appel d'origine.
la source
inspect.getfile()
retourne l'__file__
attribut si passé un objet module.inspect.currentframe()
renvoie le module. Ergo, c'est une façon coûteuse de dire__file__
.inspect.stack()
est une fonction assez chère, plus que justeinspect.currentframe()
, et elle fait aussi appelinspect.getfile()
à un objet module.la source
__file__
.os.path.dirname
vous donnera le chemin relatif à partir duquel vous exécutez le script. par exemple danspython ../../test.py
leos.path.dirname
sera../../
et non le chemin absolu vers le script. Je cherchais l'abspath mais en supprimant le nom du script. Le premier élément de sys.path est apparemment la réponsesys.path[0]
.Les suggestions marquées comme les meilleures sont toutes vraies si votre script se compose d'un seul fichier.
Si vous voulez connaître le nom de l'exécutable (c'est-à-dire le fichier racine passé à l'interpréteur python pour le programme actuel) à partir d'un fichier qui peut être importé en tant que module, vous devez le faire (supposons que cela se trouve dans un fichier nommé foo.py ):
import inspect
print inspect.stack()[-1][1]
Parce que la dernière chose (
[-1]
) sur la pile est la première chose qui y est entrée (les piles sont des structures de données LIFO / FILO).Ensuite, dans le fichier bar.py si vous
import foo
imprimez bar.py , plutôt que foo.py , qui serait la valeur de tous ces éléments:__file__
inspect.getfile(inspect.currentframe())
inspect.stack()[0][1]
la source
sys.modules['__main__'].__file__
vraiment une façon coûteuse d'orthographe .cela nous donnera uniquement le nom du fichier. c'est-à-dire si l'abspath du fichier est c: \ abcd \ abc.py alors la deuxième ligne affichera abc.py
la source
Il n'est pas tout à fait clair ce que vous entendez par "le chemin de fichier du fichier qui s'exécute actuellement dans le processus".
sys.argv[0]
contient généralement l'emplacement du script qui a été invoqué par l'interpréteur Python. Consultez la documentation sys pour plus de détails.Comme l'ont souligné @Tim et @Pat Notz, l'attribut __file__ donne accès à
la source
J'ai un script qui doit fonctionner sous environnement Windows. Ce code coupé est ce que j'ai fini avec:
c'est une décision assez bidon. Mais cela ne nécessite aucune bibliothèque externe et c'est la chose la plus importante dans mon cas.
la source
Essaye ça,
la source
Pas besoin d'inspecter ou de toute autre bibliothèque.
Cela a fonctionné pour moi lorsque j'ai dû importer un script (à partir d'un répertoire différent puis du script exécuté), qui utilisait un fichier de configuration résidant dans le même dossier que le script importé.
la source
L'
__file__
attribut fonctionne à la fois pour le fichier contenant le code d'exécution principal ainsi que pour les modules importés.Voir https://web.archive.org/web/20090918095828/http://pyref.infogami.com/__file__
la source
cela afficherait le chemin du script en cours d'exécution
la source
Je pense que c'est juste
__file__
comme si vous souhaitiez peut-être également vérifier le module d'inspection .la source
Vous pouvez utiliser
inspect.stack()
la source
Étant donné que Python 3 est assez courant, je voulais inclure une
pathlib
réponse, car je pense que c'est probablement maintenant un meilleur outil pour accéder aux informations sur les fichiers et les chemins.Si vous recherchez le répertoire du fichier en cours, c'est aussi simple que d'ajouter
.parent
à laPath()
déclaration:la source
la source
Cela devrait fonctionner:
la source
la source
Pour obtenir le répertoire d'exécution du script
la source
J'ai toujours utilisé la fonction os de Current Working Directory, ou CWD. Cela fait partie de la bibliothèque standard et est très facile à implémenter. Voici un exemple:
la source
python script.py
commande dans le même dossier que vous êtes déjà, alors qu'en réalité, c'est la même chose que l'exécutionpwd
sur Linux.J'ai utilisé l'approche avec __file__
os.path.abspath(__file__)
mais il y a une petite astuce, elle retourne le fichier .py lorsque le code est exécuté la première fois, les prochaines exécutions donnent le nom du fichier * .pyc
donc je suis resté avec:
inspect.getfile(inspect.currentframe())
ou
sys._getframe().f_code.co_filename
la source
J'ai écrit une fonction qui prend en compte le débogueur d' éclipse et unittest . Il renvoie le dossier du premier script que vous lancez. Vous pouvez éventuellement spécifier la var __file__ , mais l'essentiel est que vous n'avez pas à partager cette variable dans toute votre hiérarchie d'appel .
Peut-être que vous pouvez gérer d'autres empiler des cas particuliers que je n'ai pas vus, mais pour moi, ça va.
la source
Pour conserver la cohérence de la migration entre les plates-formes (macOS / Windows / Linux), essayez:
path = r'%s' % os.getcwd().replace('\\','/')
la source
Le moyen le plus simple est:
dans script_1.py:
dans script_2.py:
PS: J'ai essayé
execfile
, mais comme il lit script_2.py sous forme de chaîne, je suissys.argv[0]
retourné<string>
.la source
Voici ce que j'utilise pour pouvoir lancer mon code n'importe où sans problème.
__name__
est toujours défini, mais__file__
n'est défini que lorsque le code est exécuté en tant que fichier (par exemple pas dans IDLE / iPython).Alternativement, cela peut s'écrire:
la source
La plupart de ces réponses ont été écrites en Python version 2.x ou antérieure. Dans Python 3.x, la syntaxe de la fonction d'impression a changé pour exiger des parenthèses, c'est-à-dire print ().
Donc, cette réponse antérieure au meilleur score de user13993 en Python 2.x:
Devient en Python 3.x:
la source
si vous voulez juste le nom de fichier sans
./
ou.py
vous pouvez essayer cecifile_name
affichera le script de test, vous pouvez générer ce que vous voulez en modifiant l'index à l'intérieur []la source
la source