Как мне получить путь и имя файла, который в настоящее время выполняется?



у меня есть скрипты, вызывающие другие файлы скриптов, но мне нужно получить путь к файлу, который в настоящее время выполняется в процессе.



например, допустим, у меня есть три файла. Используя execfile:





  • script_1.py звонки script_2.py.

  • в свою очередь script_2.py звонки script_3.py.


как я могу получить имя файла и путь script_3.py,из кода script_3.py, без необходимо передать эту информацию в качестве аргументов от script_2.py?



(заключение os.getcwd() возвращает путь к файлу исходного исходного сценария, а не к текущему файлу.)

554   23  

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__))

нет необходимости проверять или любой другой библиотеки.

это сработало для меня, когда мне пришлось импортировать скрипт (из другого каталога, а затем выполненный скрипт), который использовал файл конфигурации, находящийся в той же папке, что и импортированный скрипт.

import sys

print sys.path[0]

это выведет путь к текущему исполняемому скрипту

Я думаю, что это просто __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 sys
print sys.argv[0]

Это должно работать:

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

    Ничего не найдено.