Python 前置脚本';将目录转换为字符串

Python 前置脚本';将目录转换为字符串,python,file,module,path,Python,File,Module,Path,在编写一次性脚本时,通常需要从与脚本相同的目录加载配置文件、映像或类似内容。最好不管脚本从哪个目录执行,它都能继续正常工作,所以我们可能不想简单地依赖当前的工作目录 如果在使用它的同一个文件中定义了这样的内容,则可以使用: from os.path import abspath, dirname, join def prepend_script_directory(s): here = dirname(abspath(__file__)) return join(here, s

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

如果在使用它的同一个文件中定义了这样的内容,则可以使用:

from os.path import abspath, dirname, join

def prepend_script_directory(s):
    here = dirname(abspath(__file__))
    return join(here, s)
不希望将相同的函数复制粘贴或重写到每个模块中,但存在一个问题:如果将其移动到单独的库中,并作为函数导入,
\uuuuuuu file\uuuuu
现在引用了其他模块,结果不正确

我们也许可以用它来代替,但似乎
sys.argv
也不可靠

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

如何稳健而正确地编写
prepend\u script\u目录?

我认为它味道不好的原因是
$PYTHONPATH
(或
sys.path
)是正确的通用机制。

无论何时执行,我个人都会将
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__'])
你想要


在我的机器上,如果从相对路径导入了
\uuu name\uu
,则返回相对于当前目录的路径。如果这对您来说是个问题,您可能仍然希望通过
os.path.abspath()
。@wim:这就是为什么人们通常不赞成它=)@ninjagecko:
os.path.split(\uu file\uuuuu)[0]
更简单和明确地写为
os.path.dirname(\uu file\uuu)
“Hacky Debuchery”肯定会咬到你或下一个可怜的屁股。“如果实施过程很难解释,那是个坏主意。”是的,它确实咬了我一口。。似乎
\uuuu文件\uuuuu
是由
runpy
或模块加载程序设置的(我不确定确切时间),它可以是相对路径,也可以是绝对路径,具体取决于您执行脚本的方式。在相对路径的情况下,如果调用了
os.chdir()
,则不会更新相对路径,因此如果在同一文件中调用了先前的
os.chdir()
,则使用
os.path.abspath(\uu文件\uuuu)
,将得到错误的结果。这有意义吗P
import pkg_resources
foo_fname = pkg_resources.resource_filename(__name__, "foo.txt")