如何获取当前正在执行的文件的路径和名称?

python scripting file

497173 观看

29回复

85637 作者的声誉

我有脚本调用其他脚本文件,但我需要获取当前在该进程中运行的文件的文件路径。

例如,假设我有三个文件。使用execfile

  • script_1.py电话script_2.py
  • 反过来,script_2.py打电话script_3.py

我怎样才能获得的文件名和路径script_3.py从内部代码script_3.py,而无需从传递这些信息作为参数script_2.py

(执行os.getcwd()返回原始起始脚本的文件路径而不是当前文件的。)

作者: Ray Vega 的来源 发布者: 2008 年 9 月 8 日

回应 (29)


12

165279 作者的声誉

“当前在进程中运行的文件的文件路径”是什么意思并不完全清楚。 sys.argv[0]通常包含Python解释器调用的脚本的位置。有关更多详细信息,请查看sys文档

正如@Tim和@Pat Notz指出的那样,__ file__属性提供了访问权限

加载模块的文件,如果是从文件加载的

作者: Blair Conrad 发布者: 08.09.2008 07:42

5

139462 作者的声誉

我认为这__file__ 听起来像你也可能想要检查检查模块

作者: Pat Notz 发布者: 08.09.2008 07:44

8

137553 作者的声誉

__file__属性适用于包含主执行代码的文件以及导入的模块。

请参阅https://web.archive.org/web/20090918095828/http://pyref.infogami.com/__file__

作者: Readonly 发布者: 08.09.2008 07:56

240

139462 作者的声誉

决定

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
作者: Pat Notz 发布者: 08.09.2008 11:02

4

19958 作者的声誉

您可以使用 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'
作者: PabloG 发布者: 09.09.2008 12:00

540

5501 作者的声誉

__file__

正如其他人所说。您可能还想使用os.path.realpath来消除符号链接:

import os

os.path.realpath(__file__)
作者: user13993 发布者: 23.12.2009 08:33

6

859 作者的声誉

import sys

print sys.path[0]

这将打印当前正在执行的脚本的路径

作者: appusajeev 发布者: 02.01.2010 06:34

37

0 作者的声誉

如果您的脚本只包含一个文件,那么标记为最佳的建议都是正确的。

如果你想从可以作为模块导入的文件中找出可执行文件的名称(即传递给当前程序的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]
作者: user282406 发布者: 26.02.2010 10:25

3

2614 作者的声誉

import sys
print sys.argv[0]
作者: WBAR 发布者: 19.04.2010 07:47

0

33 作者的声誉

我使用__file__的方法,
os.path.abspath(__file__)
但有一个小技巧,它在第一次运行代码时返回.py文件,下次运行时给出* .pyc文件的名称,
所以我留下来:
inspect.getfile(inspect.currentframe())
或者
sys._getframe().f_code.co_filename

作者: mik80 发布者: 01.03.2011 09:23

69

1955 作者的声誉

我认为这更清洁:

import inspect
print inspect.stack()[0][1]

并获得相同的信息:

print inspect.getfile(inspect.currentframe())

其中[0]是堆栈中的当前帧(堆栈顶部),[1]是文件名,增加到堆栈中向后,即

print inspect.stack()[1][1]

将是调用当前帧的脚本的文件名。此外,使用[-1]将使您到达堆栈的底部,即原始调用脚本。

作者: Usagi 发布者: 08.07.2011 05:50

10

593 作者的声誉

我有一个必须在Windows环境下工作的脚本。剪切的代码是我完成的:

import os,sys
PROJECT_PATH = os.path.abspath(os.path.split(sys.argv[0])[0])

这是一个非常糟糕的决定。但它不需要外部库,在我的情况下它是最重要的。

作者: garmoncheg 发布者: 08.08.2012 09:42

-3

3 作者的声誉

如果您只想要文件名,./或者.py您可以试试这个

filename = testscript.py
file_name = __file__[2:-3]

file_name 将打印testscript您可以通过更改[]内的索引生成任何您想要的内容

作者: sapam 发布者: 20.01.2013 08:52

-3

11 作者的声誉

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)
作者: jscabuzzo 发布者: 24.01.2013 02:43

13

159 作者的声誉

import os
print os.path.basename(__file__)

这将只给我们文件名。即如果文件的abspath是c:\ abcd \ abc.py,那么第二行将打印abc.py

作者: vishal ekhe 发布者: 11.08.2013 03:05

8

321 作者的声誉

import os
os.path.dirname(os.path.abspath(__file__))

无需检查或任何其他图书馆。

当我必须导入脚本(从不同的目录然后执行的脚本)时,这对我有用,它使用与导入的脚本位于同一文件夹中的配置文件。

作者: Kwuite 发布者: 24.06.2014 03:04

40

837 作者的声誉

import os
os.path.dirname(__file__) # relative directory path
os.path.abspath(__file__) # absolute file path
os.path.basename(__file__) # the file name only
作者: Neal Xiong 发布者: 06.02.2015 01:05

2

14537 作者的声誉

这应该工作:

import os,sys
filename=os.path.basename(os.path.realpath(sys.argv[0]))
dirname=os.path.dirname(os.path.realpath(sys.argv[0]))
作者: Jahid 发布者: 14.06.2015 04:37

80

8042 作者的声誉

更新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,切换到包可能更清楚,因此可以使用from lib import bar- 只需将空__init__.py文件添加到两个文件夹中。

对于Python 3,execfile不存在 - 最近的替代方案是exec(open(<filename>).read()),虽然这会影响堆栈帧。这是最简单的使用import fooimport lib.bar- 不需要__init__.py文件。

另请参见import和execfile之间的区别


原答案:

这是一个基于此线程中的答案的实验 - 在Windows上使用Python 2.7.10。

基于堆栈的那些似乎只能提供可靠的结果。最后两个语法最短,即 -

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

以下是将这些作为函数添加到sys中!感谢@Usagi和@pablog

基于以下三个文件,并从其文件夹中运行main.py python main.py(还尝试了具有绝对路径的execfiles并从单独的文件夹调用)。

C:\ filepaths \ main.py: execfile('foo.py')
C:\ filepaths \ foo.py:C execfile('lib/bar.py')
: \ 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
作者: Brian Burns 发布者: 06.08.2015 10:50

0

357 作者的声誉

我写了一个函数,它考虑了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_))
作者: hayj 发布者: 14.06.2016 03:06

1

10370 作者的声誉

获取执行脚本的目录

 print os.path.dirname( inspect.getfile(inspect.currentframe()))
作者: pbaranski 发布者: 10.05.2017 10:51

0

145 作者的声誉

要保持跨平台(macOS / Windows / Linux)的迁移一致性,请尝试:

path = r'%s' % os.getcwd().replace('\\','/')

作者: Qiao Zhang 发布者: 12.04.2018 05:19

0

520 作者的声誉

最简单的方法是:

script_1.py中:

import subprocess
subprocess.call(['python3',<path_to_script_2.py>])

script_2.py中:

sys.argv[0]

PS:我已经尝试了execfile,但是因为它将script_2.py作为字符串读取,所以sys.argv[0]返回了<string>

作者: Lucas Azevedo 发布者: 08.06.2018 12:29

-2

97 作者的声誉

大多数答案都是用Python 2.x或更早版本编写的。在Python 3.x中,print函数的语法已更改为需要括号,即print()。

所以,Python 2.x中来自user13993的早期高分答案:

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

成为Python 3.x:

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
作者: user3339488 发布者: 09.11.2018 01:15

0

44 作者的声誉

我一直只使用当前工作目录的OS功能,或CWD。这是标准库的一部分,非常容易实现。这是一个例子:

    import os
    base_directory = os.getcwd()
作者: Ethan J. 发布者: 23.01.2019 04:31

7

132 作者的声誉

试试这个,

import os
os.path.dirname(os.path.realpath(__file__))
作者: Soumyajit 发布者: 22.02.2019 05:31

2

795 作者的声誉

print(__file__)
print(__import__("pathlib").Path(__file__).parent)
作者: BaiJiFeiLong 发布者: 05.05.2019 01:19

0

1463 作者的声誉

这是我使用的,所以我可以把我的代码扔到任何地方而没有问题。__name__始终定义,但__file__仅在代码作为文件运行时定义(例如,不在IDLE / iPython中)。

    if '__file__' in globals():
        self_name = globals()['__file__']
    elif '__file__' in locals():
        self_name = locals()['__file__']
    else:
        self_name = __name__

或者,这可以写成:

self_name = globals().get('__file__', locals().get('__file__', __name__))
作者: craymichael 发布者: 28.06.2019 01:28

0

2138 作者的声誉

由于Python 3是相当主流的,我想要包含一个pathlib答案,因为我相信它现在可能是访问文件和路径信息的更好工具。

from pathlib import Path

current_file: Path = Path(__file__).resolve()

如果您正在寻找当前文件的目录,那么就像添加.parentPath()语句一样简单:

current_path: Path = Path(__file__).parent.resolve()
作者: Doug 发布者: 23.08.2019 07:19
32x32