如何获取当前执行文件的路径?

234 投票
13 回答
192223 浏览
提问于 2025-04-15 21:33

在Python中,有没有一种通用的方法可以找到当前正在执行的文件的路径呢?

失败的方法

path = os.path.abspath(os.path.dirname(sys.argv[0]))

如果你是从另一个目录的Python脚本中运行这个代码,比如在2.x版本中使用execfile,这个方法就不管用了。

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

我发现这个方法在以下情况下也不奏效:

  • py2exe没有__file__这个属性,不过有解决办法
  • 当代码是通过IDLE中的execute()运行时,这时候也没有__file__这个属性
  • Mac OS X v10.6(雪豹)上,我会遇到NameError: global name '__file__' is not defined的错误

测试案例

目录结构

C:.
|   a.py
\---subdir
        b.py

a.py的内容

#! /usr/bin/env python
import os, sys

print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print

execfile("subdir/b.py")

subdir/b.py的内容

#! /usr/bin/env python
import os, sys

print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print

运行python a.py的输出(在Windows上)

a.py: __file__= a.py
a.py: os.getcwd()= C:\zzz

b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:\zzz

相关内容(但这些答案不完整)

13 个回答

31

这个解决方案在可执行文件中也很可靠:

import inspect, os.path

filename = inspect.getframeinfo(inspect.currentframe()).filename
path     = os.path.dirname(os.path.abspath(filename))
103

首先,你需要从 inspectos 这两个模块导入一些东西。

from inspect import getsourcefile
from os.path import abspath

接下来,无论你想从哪里找到源文件,你只需要使用下面的代码。

abspath(getsourcefile(lambda:0))
89

你不能直接找到正在执行的主脚本的位置。毕竟,有时候这个脚本根本不是来自一个文件。例如,它可能是从交互式解释器中输入的,或者是动态生成的代码,只存在于内存中。

不过,你可以可靠地找到一个模块的位置,因为模块总是从文件中加载。如果你用下面的代码创建一个模块,并把它放在和主脚本同一个文件夹里,那么主脚本就可以导入这个模块,从而找到自己的位置。

some_path/module_locator.py:

def we_are_frozen():
    # All of the modules are built-in to the interpreter, e.g., by py2exe
    return hasattr(sys, "frozen")

def module_path():
    encoding = sys.getfilesystemencoding()
    if we_are_frozen():
        return os.path.dirname(unicode(sys.executable, encoding))
    return os.path.dirname(unicode(__file__, encoding))

some_path/main.py:

import module_locator
my_path = module_locator.module_path()

如果你有多个主脚本在不同的文件夹里,你可能需要多个副本的module_locator。

当然,如果你的主脚本是由其他工具加载的,而这个工具不允许你导入和脚本在同一个地方的模块,那你就没办法了。在这种情况下,你想要的信息在你的程序中根本不存在。你最好的选择就是向这个工具的作者反馈问题。

撰写回答