Как мне получить путь и имя файла, который в настоящее время выполняется?
у меня есть скрипты, вызывающие другие файлы скриптов, но мне нужно получить путь к файлу, который в настоящее время выполняется в процессе.
например, допустим, у меня есть три файла. Используя execfile:
script_1.pyзвонкиscript_2.py.- в свою очередь
script_2.pyзвонкиscript_3.py.
как я могу получить имя файла и путь script_3.py,из кода script_3.py, без необходимо передать эту информацию в качестве аргументов от script_2.py?
(заключение os.getcwd() возвращает путь к файлу исходного исходного сценария, а не к текущему файлу.)
23 ответов:
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__как говорили другие. Вы также можете использовать ОС.путь.реального пути для устранения символических ссылок:
import os os.path.realpath(__file__)
вот эксперимент, основанный на ответах в этой теме - С Python 2.7.10 на Windows.
стековые являются единственными, которые, кажется, дают надежные результаты. Последние два имеют самый короткий синтаксис, т. е. -
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вот к этим добавляется sys как функции! Кредит @Usagi и @pablog
на основе следующих трех файлов и работает script1.py из своей папки с
python script1.py(тоже пробовал execfiles с абсолютными путями и вызовом из отдельной папки).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
Я думаю, что это чище:
import inspect print inspect.stack()[0][1]и получает ту же информацию, что и:
print inspect.getfile(inspect.currentframe())где [0] - текущий кадр в стеке (верхняя часть стека) и [1] - это имя файла, увеличьте, чтобы вернуться в стек, т. е.
print inspect.stack()[1][1]будет имя файла сценария, который вызвал текущий кадр. Кроме того, использование [-1] приведет вас к нижней части стека, оригинального вызывающего скрипта.
предложения, отмеченные как лучшие, все верны, если ваш скрипт состоит только из одного файла.
если вы хотите узнать имя исполняемого файла (т. е. корневого файла, переданного интерпретатору python для текущей программы) из файла, который может быть импортирован как модуль, вам нужно сделать это (предположим, что это в файле с именем foo.py):
import inspect
print inspect.stack()[-1][1]потому что последнее (
[-1]) в стеке является первое, что вошло в него (стеки-это структуры данных LIFO/FILO).затем в файле bar.py Если ты
import fooон будет печатать bar.py, а не foo.py, который был бы значением всех этих:
__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__)это даст нам только именем. т. е. если abspath файла c:\abcd\abc.py тогда 2-я строка будет печатать abc.py
не совсем понятно, что вы подразумеваете под "путь к файлу, который в настоящее время выполняется в процессе".
sys.argv[0]обычно содержит расположение скрипта, который был вызван интерпретатором Python. Проверьте документация sys для более подробной информации.как указали @Tim и @Pat Notz, атрибут __file_ _ предоставляет доступ к
файл, из которого был создан модуль загружен, если он был загружен из файл
У меня есть скрипт, который должен работать в среде Windows. Этот код обрезан - это то, с чем я закончил:
import os,sys PROJECT_PATH = os.path.abspath(os.path.split(sys.argv[0])[0])это решение довольно суховато. Но это не требует внешних библиотек, и это самое главное в моем случае.
на
__file__атрибут работает как для файла, содержащего основной код выполнения, так и для импортированных модулей.см https://web.archive.org/web/20090918095828/http://pyref.infogami.com/__file__
import os os.path.dirname(os.path.abspath(__file__))нет необходимости проверять или любой другой библиотеки.
это сработало для меня, когда мне пришлось импортировать скрипт (из другого каталога, а затем выполненный скрипт), который использовал файл конфигурации, находящийся в той же папке, что и импортированный скрипт.
Я думаю, что это просто
__file__похоже, вы также можете оформить заказ модуль проверить.
можно использовать
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'
Это должно работать:
import os,sys filename=os.path.basename(os.path.realpath(sys.argv[0])) dirname=os.path.dirname(os.path.realpath(sys.argv[0]))
чтобы получить каталог выполнения скрипта
print os.path.dirname( inspect.getfile(inspect.currentframe()))
чтобы сохранить согласованность миграции между платформами (macOS / Windows / Linux), попробуйте:
path = r'%s' % os.getcwd().replace('\','/')
я использовал подход с _ _ file__
os.path.abspath(__file__)
но есть небольшой трюк, он возвращает файл .py когда код выполняется в первый раз, следующие запуски дают имя *.pyc file
поэтому я остался с:inspect.getfile(inspect.currentframe())
илиsys._getframe().f_code.co_filename
Я написал функцию, которая учитывает eclipse отладчик и unittest. Он возвращает папку первого скрипта, который вы запускаете. Вы можете дополнительно указать _ _ file__ var, но главное, что вам не нужно делиться этой переменной по всем вашим вызов иерархии.
может быть, вы можете обрабатывать другие стека конкретных случаев я не видел, но для меня это нормально.
import inspect, os def getRootDirectory(_file_=None): """ Get the directory of the root execution file Can help: http://stackoverflow.com/questions/50499/how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executing For eclipse user with unittest or debugger, the function search for the correct folder in the stack You can pass __file__ (with 4 underscores) if you want the caller directory """ # 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_))
самый простой способ-это:
in script_1.py:
import subprocess subprocess.call(['python3',<path_to_script_2.py>])in script_2.py:
sys.argv[0]P. S.: Я пробовал
execfile, но так как он читает script_2.py как строка,sys.argv[0]вернулся<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)
если вы хотите только имя файла без
./или.pyвы можете попробовать этотfilename = testscript.py file_name = __file__[2:-3]
file_nameбудет печатать testscript вы можете создать все, что вы хотите, изменив индекс внутри []
Comments