我想知道在Python中确定当前脚本目录的最佳方法是什么。

我发现,由于调用Python代码的方法很多,很难找到一个好的解决方案。

以下是一些问题:

如果脚本使用exec, execfile执行,则__file__未定义 __module__只在模块中定义

用例:

。/ myfile.py python myfile.py / somedir / myfile.py python somedir / myfile.py Execfile ('myfile.py')(来自另一个脚本,可以位于另一个目录,并且可以有另一个当前目录。

我知道没有完美的解决方案,但我正在寻找解决大多数情况的最佳方法。

最常用的方法是os.path.dirname(os.path.abspath(__file__)),但如果你用exec()从另一个脚本执行脚本,这就行不通了。

警告

任何使用当前目录的解决方案都会失败,这可以根据脚本调用的方式有所不同,也可以在运行的脚本中更改。


当前回答

os.path……方法在Python 2中是“已完成的事情”。

在Python 3中,你可以找到script的目录,如下所示:

from pathlib import Path
script_path = Path(__file__).parent

其他回答

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

确实是你能得到的最好的。

使用exec/execfile执行脚本是不寻常的;通常情况下,您应该使用模块基础结构来加载脚本。如果你必须使用这些方法,我建议在你传递给脚本的全局变量中设置__file__,这样脚本就可以读取该文件名。

没有其他方法可以在执行代码中获取文件名:正如您所注意到的,CWD可能在一个完全不同的地方。

希望这有助于:- 如果你在任何地方运行一个脚本/模块,你将能够访问__file__变量,这是一个表示脚本位置的模块变量。

另一方面,如果你正在使用解释器,你不能访问这个变量,在那里你会得到一个名字NameError和os.getcwd()会给你错误的目录,如果你从其他地方运行文件。

这个解决方案应该会在所有情况下给你你想要的:

from inspect import getsourcefile
from os.path import abspath
abspath(getsourcefile(lambda:0))

我还没有彻底测试,但它解决了我的问题。

import os
cwd = os.getcwd()

做你想做的事?我不确定你说的“当前脚本目录”到底是什么意思。您给出的用例的预期输出是什么?

因为以前的答案需要你导入一些模块,我想我会写一个答案,不。如果您不想导入任何东西,请使用下面的代码。

this_dir = '/'.join(__file__.split('/')[:-1])
print(this_dir)

如果脚本在/path/to/script.py上,那么将打印/path/to。注意,这将在终端上抛出错误,因为没有执行任何文件。这基本上是从__file__解析目录,删除它的最后一部分。在本例中,/script.py被删除以生成输出/路径/到。

如果您真的想了解通过execfile(…)调用脚本的情况,可以使用inspect模块推断文件名(包括路径)。据我所知,这将适用于你列出的所有情况:

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