在脚本目录前添加字符串


问题内容

编写一次性脚本时,通常需要从与脚本相同的目录中加载配置文件,映像或类似内容。最好无论脚本从哪个目录执行,它都应继续正常工作,因此我们可能不想简单地依赖当前的工作目录。

如果在您从以下位置使用它的同一文件中定义了这样的内容,则它会很好地起作用:

from os.path import abspath, dirname, join

def prepend_script_directory(s):
    here = dirname(abspath(__file__))
    return join(here, s)

不希望将相同的函数复制粘贴或重写到每个模块中,但是存在一个问题:如果将其移到单独的库中并作为函数导入,__file__则现在引用其他模块,结果不正确。

我们也许可以改用它,但是似乎sys.argv也不可靠。

def prepend_script_directory(s):
    here = dirname(abspath(sys.argv[0]))
    return join(here, s)

如何prepend_script_directory稳健正确地写作?


问题答案:

os.chdir每当执行脚本时,我个人都会进入脚本目录。只是:

import os
os.chdir(os.path.split(__file__)[0])

但是,如果您确实想将此内容重构为库,则本质上是需要一个知道其调用者状态的函数。因此,您必须做到

prepend_script_directory(__file__, blah)

如果你只是想写

prepend_script_directory(blah)

您必须使用堆栈框架执行特定于cpython的技巧:

import inspect

def getCallerModule():
    # gets globals of module called from, and prints out __file__ global
    print(inspect.currentframe().f_back.f_globals['__file__'])