Comment puis-je obtenir le chemin d'accès et nom du fichier qui est en cours d'exécution?
j'ai des scripts appelant d'autres fichiers de script mais j'ai besoin d'obtenir le chemin de fichier du fichier qui est actuellement en cours d'exécution dans le processus.
Par exemple, disons que j'ai trois fichiers. En utilisant execfile :
-
script_1.py
appelsscript_2.py
. - à son tour,
script_2.py
appellescript_3.py
.
Comment puis-je obtenir le nom de fichier et le chemin script_3.py
, de code dans script_3.py
, sans avoir à passer cette information comme arguments de script_2.py
?
(L'exécution os.getcwd()
renvoie le chemin de fichier du script de départ original et non celui du fichier courant.)
23 réponses
p1.py:
execfile("p2.py")
p2.py:
import inspect, os
print inspect.getfile(inspect.currentframe()) # script filename (usually with path)
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory
__file__
comme d'autres l'ont dit. Vous pouvez également utiliser os.chemin.realpath pour éliminer symlinks:
import os
os.path.realpath(__file__)
Voici une expérience basée sur les réponses dans ce thread - avec Python 2.7.10 sur Windows.
La pile, ceux sont les seuls qui semblent donner des résultats fiables. Les deux derniers ont la syntaxe la plus courte , ie -
print os.path.abspath(inspect.stack()[0][1]) # C:\testpath\lib\script3.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])) # C:\testpath\lib
c'est pour ceux-ci étant ajoutés à sys comme des fonctions! Crédit à @Usagi et @pablog
Basé sur les trois fichiers suivants, et en cours d'exécution script1.py de son dossier avec python script1.py
(également essayé exécufiles avec des chemins absolus et appel à partir d'un dossier séparé).
C:\testpath\script1.py: execfile('script2.py')
C:\testpath\script2.py: execfile('lib/script3.py')
C:\testpath\lib\script3.py:
import sys
import os
import inspect
print "Python " + sys.version
print
print __file__ # script1.py
print sys.argv[0] # script1.py
print inspect.stack()[0][1] # lib/script3.py
print sys.path[0] # C:\testpath
print
print os.path.realpath(__file__) # C:\testpath\script1.py
print os.path.abspath(__file__) # C:\testpath\script1.py
print os.path.basename(__file__) # script1.py
print os.path.basename(os.path.realpath(sys.argv[0])) # script1.py
print
print sys.path[0] # C:\testpath
print os.path.abspath(os.path.split(sys.argv[0])[0]) # C:\testpath
print os.path.dirname(os.path.abspath(__file__)) # C:\testpath
print os.path.dirname(os.path.realpath(sys.argv[0])) # C:\testpath
print os.path.dirname(__file__) # (empty string)
print
print inspect.getfile(inspect.currentframe()) # lib/script3.py
print os.path.abspath(inspect.getfile(inspect.currentframe())) # C:\testpath\lib\script3.py
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # C:\testpath\lib
print
print os.path.abspath(inspect.stack()[0][1]) # C:\testpath\lib\script3.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])) # C:\testpath\lib
print
je pense que c'est plus propre:
import inspect
print inspect.stack()[0][1]
et obtient les mêmes informations que:
print inspect.getfile(inspect.currentframe())
où [0] est la trame courante dans la pile (en haut de la pile) et [1] est pour le nom du fichier, l'augmentation pour revenir en arrière dans la pile i.e.
print inspect.stack()[1][1]
serait le nom du fichier du script qui a appelé le cadre courant. En outre, l'utilisation de [-1] vous mènera au bas de la pile, le script d'appel original.
les suggestions indiquées comme étant 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.-à-d. le fichier racine passé à l'interpréteur python pour le programme courant) à partir d'un fichier qui peut être importé en tant que module, vous devez le faire (supposons que c'est 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).
puis dans le fichier bar.py si vous import foo
il imprimera bar.py , plutôt que foo.py , qui serait la valeur de tous ces:
-
__file__
-
inspect.getfile(inspect.currentframe())
-
inspect.stack()[0][1]
import os
os.path.dirname(__file__) # relative directory path
os.path.abspath(__file__) # absolute file path
os.path.basename(__file__) # the file name only
import os
print os.path.basename(__file__)
cela nous donnera le nom du fichier seulement. c'est-à-dire si abspath of file est c:\abcd\abc.py alors la 2e ligne s'affichera abc.py
ce n'est pas tout à fait clair ce que vous voulez dire par"le chemin du fichier qui est actuellement en cours d'exécution dans le processus".
sys.argv[0]
contient habituellement l'emplacement du script qui a été invoqué par L'interpréteur Python.
Consultez la documentation sys pour plus de détails.
comme @Tim et @Pat Notz L'ont fait remarquer, l'attribut _ _ file _ _ donne accès à
le fichier à partir duquel le module a été charger, s'il a été chargé à partir d'un fichier
j'ai un script qui doit fonctionner sous environnement windows. C'est ce code que j'ai terminé avec:
import os,sys
PROJECT_PATH = os.path.abspath(os.path.split(sys.argv[0])[0])
c'est une sacrée décision. Mais il ne nécessite pas de bibliothèques externes et c'est la chose la plus importante dans mon cas.
l'attribut __file__
fonctionne aussi bien pour le fichier contenant le code d'exécution principal que pour les modules importés.
voir https://web.archive.org/web/20090918095828/http://pyref.infogami.com/__file _ _ _
import os
os.path.dirname(os.path.abspath(__file__))
pas besoin d'inspecter ou toute autre bibliothèque.
cela a fonctionné pour moi quand j'ai dû importer un script (à partir d'un répertoire différent puis le script exécuté), qui utilisait un fichier de configuration résidant dans le même dossier que le script importé.
import sys
print sys.path[0]
cela imprimerait le chemin du script en cours d'exécution
je pense que c'est juste __file__
sonne comme vous pouvez également vouloir vérifier le module d'inspection .
vous pouvez utiliser inspect.stack()
import inspect,os
inspect.stack()[0] => (<frame object at 0x00AC2AC0>, 'g:\Python\Test\_GetCurrentProgram.py', 15, '<module>', ['print inspect.stack()[0]\n'], 0)
os.path.abspath (inspect.stack()[0][1]) => 'g:\Python\Test\_GetCurrentProgram.py'
cela devrait fonctionner:
import os,sys
filename=os.path.basename(os.path.realpath(sys.argv[0]))
dirname=os.path.dirname(os.path.realpath(sys.argv[0]))
pour obtenir le répertoire d'exécution du script
print os.path.dirname( inspect.getfile(inspect.currentframe()))
Pour garder la migration de la cohérence entre les plates-formes (macOS/Windows/Linux), essayez:
path = r'%s' % os.getcwd().replace('\','/')
j'ai utilisé l'approche par __fichier__
os.path.abspath(__file__)
mais il y a un petit truc, il renvoie le .fichier py
quand le code est lancé la première fois,
exécute ensuite donner le nom de *.dossier pyc
alors je suis resté avec:
inspect.getfile(inspect.currentframe())
ou
sys._getframe().f_code.co_filename
j'ai écrit une fonction qui tiennent compte de l'éclipse débogueur et unittest . Il renvoie le dossier du premier script que vous lancez. Vous pouvez éventuellement spécifier le fichier __fichier__ _ var, mais l'essentiel est que vous n'avez pas à partager cette variable à travers toute votre appelant la hiérarchie .
peut-être que vous pouvez gérer d'autres empiler des cas particuliers que je n'ai pas vu, mais pour moi c'est OK.
import inspect, os
def getRootDirectory(_file_=None):
"""
Get the directory of the root execution file
Can help: /q/how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executing-50544/"""
# If we don't have the __file__ :
if _file_ is None:
# We get the last :
rootFile = inspect.stack()[-1][1]
folder = os.path.abspath(rootFile)
# If we use unittest :
if ("/pysrc" in folder) & ("org.python.pydev" in folder):
previous = None
# We search from left to right the case.py :
for el in inspect.stack():
currentFile = os.path.abspath(el[1])
if ("unittest/case.py" in currentFile) | ("org.python.pydev" in currentFile):
break
previous = currentFile
folder = previous
# We return the folder :
return os.path.dirname(folder)
else:
# We return the folder according to specified __file__ :
return os.path.dirname(os.path.realpath(_file_))
la manière la plus simple est:
in script_1.py:
import subprocess
subprocess.call(['python3',<path_to_script_2.py>])
in script_2.py:
sys.argv[0]
P. S.: j'ai essayé execfile
, mais puisqu'il lit script_2.py comme une chaîne, sys.argv[0]
retourné <string>
.
import os
import wx
# return the full path of this file
print(os.getcwd())
icon = wx.Icon(os.getcwd() + '/img/image.png', wx.BITMAP_TYPE_PNG, 16, 16)
# put the icon on the frame
self.SetIcon(icon)
si vous voulez juste le nom du fichier sans ./
ou .py
vous pouvez essayer ce
filename = testscript.py
file_name = __file__[2:-3]
file_name
imprimera testscript
vous pouvez générer ce que vous voulez en changeant l'index à l'intérieur []