将脚本目录添加到字符串前面
在写一些临时的小脚本时,通常需要从和脚本在同一个文件夹里的配置文件、图片或者其他东西加载数据。最好是无论脚本从哪个目录执行,这个功能都能正常工作,所以我们可能不想单纯依赖当前的工作目录。
如果在同一个文件里定义一个这样的功能,效果是不错的:
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
这个功能呢?
3 个回答
-1
你需要用到 pkg_resources 这个工具。
import pkg_resources
foo_fname = pkg_resources.resource_filename(__name__, "foo.txt")
-1
我觉得这里有点不对劲的原因是,$PYTHONPATH
(或者说sys.path
)是正确的通用方法。
3
我个人的做法是,每次执行脚本时,直接用 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__'])