在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__属性,尽管有一个变通方法 当使用execute()从IDLE运行代码时,在这种情况下没有__file__属性 在Mac OS X v10.6(雪豹)上,我得到NameError:未定义全局名称“__file__”

测试用例

目录树

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

相关的(但这些答案是不完整的)

查找当前运行文件的路径 当前文件的路径取决于我如何执行程序 如何知道Python中运行脚本的路径? 将directory更改为Python脚本所在目录


您不能直接确定正在执行的主脚本的位置。毕竟,有时候脚本根本就不是来自文件。例如,它可能来自交互式解释器或仅存储在内存中的动态生成的代码。

但是,您可以可靠地确定模块的位置,因为模块总是从文件中加载的。如果您使用以下代码创建了一个模块,并将其放在与主脚本相同的目录中,则主脚本可以导入该模块并使用它来定位自身。

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的多个副本。

当然,如果您的主脚本是由其他工具加载的,而这些工具不允许您导入与脚本共存的模块,那么您就不走运了。在这种情况下,您要查找的信息在您的程序中根本不存在。最好的办法是向工具的作者提交一个错误。


简单的回答是,没有保证的方法可以获得您想要的信息,但是有一些启发式方法在实践中几乎总是有效的。你可能会看看如何在C中找到可执行文件的位置。它从C语言的角度讨论了这个问题,但是所提出的解决方案很容易转化为Python。


我也遇到过类似的问题,我认为这可以解决问题:

def module_path(local_function):
   ''' returns the module path without the use of __file__.  Requires a function defined
   locally in the module.
   from http://stackoverflow.com/questions/729583/getting-file-path-of-imported-module'''
   return os.path.abspath(inspect.getsourcefile(local_function))

它适用于常规脚本和IDLE。我能说的就是为其他人尝试一下!

我的典型用法:

from toolbox import module_path
def main():
   pass # Do stuff

global __modpath__
__modpath__ = module_path(main)

现在我使用_modpath_而不是_file_。


首先,您需要从inspect和os导入

from inspect import getsourcefile
from os.path import abspath

接下来,无论您想从哪里找到源文件,只需使用

abspath(getsourcefile(lambda:0))

这应该在跨平台的方式(只要你没有使用解释器或其他东西):

import os, sys
non_symbolic=os.path.realpath(sys.argv[0])
program_filepath=os.path.join(sys.path[0], os.path.basename(non_symbolic))

sys。路径[0]是调用脚本所在的目录(它首先查找脚本要使用的模块)。我们可以将文件本身的名称从sys的末尾去掉。argv[0](这是我对os.path.basename所做的)。Os.path.join只是将它们以跨平台的方式连接在一起。os.path。realpath只是确保如果我们得到任何符号链接,其名称与脚本本身不同,我们仍然得到脚本的真实名称。

我没有Mac电脑;所以,我还没有在一个人身上测试过。请让我知道它是否有效,因为它似乎应该。我用Python 3.4在Linux (Xubuntu)上测试了这个功能。注意,这个问题的许多解决方案在mac上不起作用(因为我听说mac上不存在__file__)。

注意,如果您的脚本是一个符号链接,它将提供它所链接到的文件的路径(而不是符号链接的路径)。


有关相关信息,请参阅我对从父文件夹导入模块问题的回答,包括为什么我的回答不使用不可靠的__file__变量。这个简单的解决方案应该与不同的操作系统交叉兼容,因为os和inspect模块是Python的一部分。

首先,您需要导入inspect和os模块的部分内容。

from inspect import getsourcefile
from os.path import abspath

接下来,在Python代码中其他需要它的地方使用下面这行代码:

abspath(getsourcefile(lambda:0))

工作原理:

从内置模块os(下面介绍)导入abspath工具。

Mac, NT或Posix的操作系统例程,这取决于我们使用的是什么系统。

然后从内置模块inspect导入getsourcefile(下面的描述)。

从活动的Python对象中获取有用的信息。

Abspath (path)返回文件路径的绝对/完整版本 getsourcefile(lambda:0)以某种方式获取lambda函数对象的内部源文件,因此在Python shell中返回'<pyshell#nn>'或返回当前正在执行的Python代码的文件路径。

对getsourcefile(lambda:0)的结果使用abspath应该确保生成的文件路径是Python文件的完整文件路径。 这个解释的解决方案最初是基于回答“如何在Python中获取当前执行文件的路径?”的代码。


你可以使用pathlib模块中的Path:

from pathlib import Path

# ...

Path(__file__)

你可以使用call to parent在路径中更进一步:

Path(__file__).parent

这个解决方案即使在可执行文件中也是健壮的:

import inspect, os.path

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

只需添加以下内容:

from sys import *
path_to_current_file = sys.argv[0]
print(path_to_current_file)

Or:

from sys import *
print(sys.argv[0])

你只需要打电话:

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

而不是:

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

Abspath()给出了sys. exe的绝对路径。Argv[0](代码所在的文件名)和dirname()返回不带文件名的目录路径。


如果代码来自一个文件,您可以获得它的全名

sys._getframe().f_code.co_filename

还可以将函数名检索为f_code.co_name


主要思想是,有人会运行你的python代码,但你需要获得离python文件最近的文件夹。

我的解决方案是:

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

与 os.path.dirname (os.path.abspath (__file__)) 你可以用它来保存照片,输出文件,等等


import os
current_file_path=os.path.dirname(os.path.realpath('__file__'))