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

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

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

  • script_1.py调用script_2.py
  • 反过来,script_2.py调用script_3.py

我怎样才能从script_3.py*的代码中获得*script_3.py的文件名和路径,而不需要把这些信息作为参数从script_2.py中传递出来?

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

对该问题的评论 (3)
__file__

就像其他人所说的那样,你可以使用 [os.path.realpath]() 来消除符号链接。 你也可以使用 os.path.realpath 来消除符号链接。

import os

os.path.realpath(__file__)
评论(4)
解决办法

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
评论(11)

2018-11-28更新:

下面是Python 2和3的实验总结。 用

main.py - 运行 foo.py foo.py - 运行lib/bar.py。 lib/bar.py - 打印文件路径表达式。

<!--语言。 lang-none -->

| 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文件。

参见https://stackoverflow.com/questions/27517003/difference-between-import-and-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

为这些被添加到系统中的功能而干杯! 归功于 @Usagi 和 @pablog

基于以下三个文件,并从其文件夹中运行main.python main.py`(也试过用绝对路径的execfiles和从单独的文件夹调用)。

C:\filepaths\main.py。 execfile(&#39;foo.py&#39;)。 C:\filepaths\foo.py: execfile(&#39;lib/bar.py&#39;)。 C:\filepaths\libbar.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
评论(0)

我觉得这个比较干净。

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

并获得相同的信息。

print inspect.getfile(inspect.currentframe())

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

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

将是调用当前帧的脚本的文件名。 另外,使用[-1]会让你回到堆栈的最底层,即原来的调用脚本。

评论(3)
import os
os.path.dirname(__file__) # relative directory path
os.path.abspath(__file__) # absolute file path
os.path.basename(__file__) # the file name only
评论(1)

如果你的脚本只由一个文件组成,标记为最佳的建议都是正确的。

如果你想从一个可能作为模块导入的文件中找出可执行文件的名称 (即传给当前程序的根文件) 从一个可能作为模块导入的文件中找出可执行文件的名称(即传递给当前程序的 python 解释器的根文件),你需要这样做(让我们假设这是在一个名为 foo.py 的文件中)。

import inspect

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

因为堆栈上的最后一个东西([-1])就是进入堆栈的第一个东西(堆栈是LIFO/FILO数据结构)。

那么在文件bar.py中,如果你import foo,它会打印出bar.py,而不是foo.py,而foo.py是所有这些的值。

  • __file__
  • inspect.getfile(inspect.currentframe())
  • inspect.stack()[0][1]
评论(2)
import os
print os.path.basename(__file__)

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

评论(0)

你说的"当前在进程中运行的文件的文件路径"的意思并不完全清楚。 sys.argv[0]通常包含被 Python 解释器调用的脚本的位置。 查看 sys 文档 以了解更多细节。

正如 @Tim 和 @Pat Notz 所指出的, __file\ 属性提供了访问

&gt; 模块是由哪个文件

加载的文件,如果它是从一个文件中加载的

评论(1)

我有一个脚本,必须在windows环境下工作。 这段代码是我完成的。

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

这是一个相当黑的决定。 但它不需要外部库,而且在我的情况下,这是最重要的事情。

评论(1)

试试这个

import os
os.path.dirname(os.path.realpath(__file__))
评论(0)
import os
os.path.dirname(os.path.abspath(__file__))

不需要检查或任何其他库。

当我必须导入一个脚本(从不同的目录下导入,然后执行脚本),使用与导入的脚本在同一文件夹下的配置文件时,这对我来说是可行的。

评论(3)

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

参见

评论(0)
import sys

print sys.path[0]

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

评论(2)

我认为它只是__file__ 听起来你可能还想检查一下expect模块

评论(1)

你可以使用inspect.stack()

import inspect,os
inspect.stack()[0]  => (, 'g:\\Python\\Test\\_GetCurrentProgram.py', 15, '', ['print inspect.stack()[0]\n'], 0)
os.path.abspath (inspect.stack()[0][1]) => 'g:\\Python\\Test\\_GetCurrentProgram.py'
评论(0)
import sys
print sys.argv[0]
评论(1)
print(__file__)
print(__import__("pathlib").Path(__file__).parent)
评论(1)

这应该可以了。

import os,sys
filename=os.path.basename(os.path.realpath(sys.argv[0]))
dirname=os.path.dirname(os.path.realpath(sys.argv[0]))
评论(0)

要获得执行脚本的目录

 print os.path.dirname( inspect.getfile(inspect.currentframe()))
评论(0)

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

from pathlib import Path

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

如果你是在寻找当前文件的目录,就像在Path()语句中添加.parent一样简单。

current_path: Path = Path(__file__).parent.resolve()
评论(0)