У меня есть сценарии, вызывающие другие файлы сценариев, но мне нужно получить путь к файлу, который в данный момент запущен в процессе.
Например, допустим, у меня есть три файла. Используя execfile:
script_1.py
вызывает script_2.py
.script_2.py
вызывает script_3.py
.Как я могу получить имя файла и путь к script_3.py
, из кода внутри script_3.py
, без необходимости передавать эту информацию в качестве аргументов из script_2.py
?
(Выполнение os.getcwd()
возвращает исходный путь к файлу стартового скрипта, а не к текущему файлу).
__file__
как уже говорили другие. Вы также можете использовать ОС.путь.реального пути для устранения симлинки:
import os
os.path.realpath(__file__)
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
Обновление 2018-11-28:
Вот краткое изложение экспериментов с Python 2 и 3. С
main.py - работает foo.py foo.py - работает lib/bar.py lib/bar.py - отпечатки путь_к_файлу выражений
в
| Python | Run statement | Filepath expression |
|--------+---------------------+----------------------------------------|
| 2 | execfile | os.path.abspath(inspect.stack()[0][1]) |
| 2 | from lib import bar | __file__ |
| 3 | exec | (wasn't able to obtain it) |
| 3 | import lib.bar | __file__ |
Для Python 2, это может быть яснее, чтобы переключиться на пакеты, так что вы можете использовать импорт из lib-бар
- просто добавить файлы "пустые" init.py на две папки.
Для Python 3, execfile
не'т существуют - ближайшая альтернатива метод exec(открыть(<именем>).читать ()), хотя это влияет на стековых фреймов. Это'ы простой, просто использовать
импорт фу " и " импорт Либ.бар- файлов нет
init.py необходимо.
См. также https://stackoverflow.com/questions/27517003/difference-between-import-and-execfile
Оригинальный Ответ:
Вот эксперимент, на основе ответов в этой теме - С Python 2.7.10 для Windows.
Стековая те единственные, которые, кажется, чтобы дать надежные результаты. Два последних имеют самый короткий синтаксис, т. е. -
print os.path.abspath(inspect.stack()[0][1]) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])) # C:\filepaths\lib
Здесь's, чтобы эти добавляются к Сыс как функции! Кредит на @Усаги и @pablog
На основе следующих трех файлов, и запуск main.py из папки с питоном main.py` (также пробовал execfiles с абсолютными путями и вызывая из отдельной папки).
C:\filepaths\main.py: execfile('ФОО.пы')
C:\filepaths\foo.py: execfile('Либ/бар.пы')
C:\filepaths\lib\bar.py:
import sys
import os
import inspect
print "Python " + sys.version
print
print __file__ # main.py
print sys.argv[0] # main.py
print inspect.stack()[0][1] # lib/bar.py
print sys.path[0] # C:\filepaths
print
print os.path.realpath(__file__) # C:\filepaths\main.py
print os.path.abspath(__file__) # C:\filepaths\main.py
print os.path.basename(__file__) # main.py
print os.path.basename(os.path.realpath(sys.argv[0])) # main.py
print
print sys.path[0] # C:\filepaths
print os.path.abspath(os.path.split(sys.argv[0])[0]) # C:\filepaths
print os.path.dirname(os.path.abspath(__file__)) # C:\filepaths
print os.path.dirname(os.path.realpath(sys.argv[0])) # C:\filepaths
print os.path.dirname(__file__) # (empty string)
print
print inspect.getfile(inspect.currentframe()) # lib/bar.py
print os.path.abspath(inspect.getfile(inspect.currentframe())) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # C:\filepaths\lib
print
print os.path.abspath(inspect.stack()[0][1]) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])) # C:\filepaths\lib
print
Я думаю, что это чище:
import inspect
print inspect.stack()[0][1]
и получает такую же информацию, как:
print inspect.getfile(inspect.currentframe())
Где [0] - это текущий кадр стека (вершины стека) и [1] - это имя файла, увеличение возвращаться в стеке, т. е.
print inspect.stack()[1][1]
имя файла сценария, который вызвал текущий кадр. Кроме того, используя [-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
Предложения, отмеченные как лучшие, все верно, если ваш скрипт состоит из одного файла.
Если вы хотите узнать имя исполняемого файла (т. е. корень файл передается в интерпретатор Python для текущей программы) из файла, который может быть импортирован как модуль, что вам нужно сделать, это (позвольте'ы считать это в файл с именем foo.py):
проверить импорт
печать проверить.стек()[-1][1]`
Потому что последняя вещь ([-1]
) в стеке является первой вещью, которая вошла в его (стеки ЛИФО/фило структур данных).
Затем в файл bar.py если вы импорт фу
Это'МР печати bar.py, а не foo.py, что бы стоимость всех этих:
__файл__
проверить.метод getfile(проверить.свойство currentframe())
проверить.стек()[0][1]
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])
это'ы довольно суховато решение. Но он не требует никаких внешних библиотек, и это's самая важная вещь в моем случае.
import os
os.path.dirname(os.path.abspath(__file__))
Нет необходимости проверять или любой другой библиотеки.
Это работало для меня, когда я был вынужден импортировать скрипт (из разных каталогов, то выполняется скрипт), который используется файл конфигурации, проживающего в той же папке, импортированный скрипт.
Атрибут __file__
работает как для файла, содержащего основной код выполнения, так и для импортированных модулей.
См. https://web.archive.org/web/20090918095828/http://pyref.infogami.com/__file__
import sys
print sys.path[0]
это будет печатать путь в настоящее время выполнение скрипта
Вы можете использовать проверить.стек()
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'
print(__file__)
print(__import__("pathlib").Path(__file__).parent)
Начиная с версии Python 3-это довольно основным, я хотел, чтобы включить pathlib
ответ, как я считаю, что это, наверное, сейчас лучший инструмент для доступа к файлу и путь к файлу.
from pathlib import Path
current_file: Path = Path(__file__).resolve()
Если вы ищете каталог текущего файла, это так же просто, как добавление .родитель
в Path()
заявление:
current_path: Path = Path(__file__).parent.resolve()