开发者

Prepend script's directory to a string

开发者 https://www.devze.com 2023-03-17 14:13 出处:网络
When writing throwaway scripts it\'s often needed to load a configuration file, image, or some such thing from the same directory as the script. Preferably this should continue to work correctly regar

When writing throwaway scripts it's often needed to load a configuration file, image, or some such thing from the same directory as the script. Preferably this should continue to work correctly regardless of the directory the script is executed from, so we may not want to simply rely on the current working directory.

Something like this works fine if defined within the same file you're using it from:

from os.path import abspath开发者_如何学Go, dirname, join

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

It's not desirable to copy-paste or rewrite this same function into every module, but there's a problem: if you move it into a separate library, and import as a function, __file__ is now referencing some other module and the results are incorrect.

We could perhaps use this instead, but it seems like the sys.argv may not be reliable either.

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

How to write prepend_script_directory robustly and correctly?


I would personally just os.chdir into the script's directory whenever I execute it. It is just:

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

However if you did want to refactor this thing into a library, you are in essence wanting a function that is aware of its caller's state. You thus have to make it

prepend_script_directory(__file__, blah)

If you just wanted to write

prepend_script_directory(blah)

you'd have to do cpython-specific tricks with stack frames:

import inspect

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


I think the reason it doesn't smell right is that $PYTHONPATH (or sys.path) is the proper general mechanism to use.


You want pkg_resources

import pkg_resources
foo_fname = pkg_resources.resource_filename(__name__, "foo.txt")
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号