How do I get the path of the current executed file in Python?
这似乎是一个新手的问题,但事实并非如此。有些常见的方法并不适用于所有情况:
系统ARVV〔0〕这意味着使用
这意味着使用
py2exe 没有__file__ 属性,但有一个变通方法- 当使用
execute() 从空闲运行时,没有__file__ 属性 - 操作系统x 10.6,在这里我得到了
NameError: global name '__file__' is not defined 。
答案不完整的相关问题:
- python-查找正在运行的文件的路径
- 当前文件的路径取决于我如何执行程序
- 如何知道在python中运行脚本的路径?
- 将目录更改为python脚本的目录
我正在寻找一个通用的解决方案,它可以在上述所有用例中工作。
更新以下是测试用例的结果:
python a.py的输出(在Windows上)1 2 3 4 5 6 | 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 |
A.Py
1 2 3 4 5 6 7 8 9 | #! /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() execfile("subdir/b.py") |
亚DIR/B.Py
1 2 3 4 5 6 7 | #! /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() |
树
1 2 3 4 | C:. | a.py \---subdir b.py |
无法直接确定正在执行的主脚本的位置。毕竟,有时候脚本根本不是来自文件。例如,它可以来自交互式解释器或只存储在内存中的动态生成的代码。
但是,您可以可靠地确定模块的位置,因为模块总是从文件加载的。如果使用以下代码创建一个模块,并将其放在与主脚本相同的目录中,那么主脚本可以导入该模块并使用它来定位自身。
某些路径/模块定位器.py:
1 2 3 4 5 6 7 8 9 | 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)) |
一些路径/main.py:
1 2 | import module_locator my_path = module_locator.module_path() |
如果在不同的目录中有多个主脚本,则可能需要模块定位器的多个副本。
当然,如果您的主脚本是由其他一些不允许您导入与脚本共存的模块的工具加载的,那么您就走运了。在这种情况下,你所需要的信息在你的程序中根本不存在。最好的办法是向工具的作者提交一个bug。
首先,您需要从
1 2 | from inspect import getsourcefile from os.path import abspath |
接下来,无论您想从何处查找源文件,只要使用
1 | abspath(getsourcefile(lambda:0)) |
我遇到了一个类似的问题,我认为这可以解决问题:
1 2 3 4 5 | 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)) |
它适用于常规脚本和空闲脚本。我所能说的就是为别人试一试!
我的典型用法:
1 2 3 4 5 6 | from toolbox import module_path def main(): pass # Do stuff global __modpath__ __modpath__ = module_path(main) |
现在我用modpath代替file。
这个解决方案即使在可执行文件中也很健壮
1 2 3 4 | import inspect, os.path filename = inspect.getframeinfo(inspect.currentframe()).filename path = os.path.dirname(os.path.abspath(filename)) |
简短的回答是,没有保证的方法可以获得您想要的信息,但是,在实践中几乎总是有启发式方法可以工作。您可能会看到我如何在C中找到可执行文件的位置?.它从C的角度讨论了这个问题,但是所提出的解决方案很容易被转换成python。
您只需打电话:
1 | path = os.path.abspath(os.path.dirname(sys.argv[0])) |
而不是:
1 | path = os.path.dirname(os.path.abspath(sys.argv[0])) |
有关相关信息,请参阅我对从父文件夹导入模块的问题的回答,包括为什么我的回答不使用不可靠的
首先,您需要导入inspect和os模块的部分。
1 2 | from inspect import getsourcefile from os.path import abspath |
接下来,在python代码中需要的任何地方使用下面的行:
1 | abspath(getsourcefile(lambda:0)) |
它是如何工作的:
从内置模块
OS routines for Mac, NT, or Posix depending on what system we're on.
然后,从内置模块
Get useful information from live Python objects.
abspath(path) 返回文件路径的绝对/完整版本getsourcefile(lambda:0) 以某种方式获取lambda函数对象的内部源文件,因此在python shell中返回' 或返回当前正在执行的python代码的文件路径。'
在
您可以从
1 2 3 4 5 | from pathlib import Path # ... Path(__file__) |
您可以使用调用
1 | Path(__file__).parent |
这应该以跨平台的方式完成这个技巧(只要您不使用解释器或其他东西):
1 2 3 | import os, sys non_symbolic=os.path.realpath(sys.argv[0]) program_filepath=os.path.join(sys.path[0], os.path.basename(non_symbolic)) |
我没有Mac电脑,所以我还没有在上面测试过。请告诉我它是否有效,因为它似乎应该。我在Linux(Xubuntu)和Python3.4中测试了这个。请注意,这个问题的许多解决方案在Macs上不起作用(因为我听说Macs上没有
请注意,如果脚本是符号链接,它将为您提供链接到的文件的路径(而不是符号链接的路径)。
1 2 | import os current_file_path=os.path.dirname(os.path.realpath('__file__')) |
我的解决方案是:
1 2 | import os print(os.path.join(os.getcwd(), __file__)) |
如果代码来自一个文件,您可以得到它的全名
1 | sys._getframe().f_code.co_filename |
您还可以将函数名检索为
只需添加以下内容:
1 2 3 | from sys import * path_to_current_file = sys.argv[0] print(path_to_current_file) |
或:
1 2 | from sys import * print(sys.argv[0]) |