我将函数调用包装在我的初始化模块中,并使用修补 PYTHONPATH 以将当前目录添加到其中的装饰器,这样我就可以在我的模块中使用相对导入,而不必担心将包显式添加到 PYTHONPATH(根据@abarnert 的评论进行编辑)
def patch_python_path(f):
@wraps(f)
def wrap(*args, **kwargs):
ROOT = os.pathsep.join([os.path.abspath(os.path.dirname(__file__))])
if not os.environ.has_key("PYTHONPATH"):
os.environ["PYTHONPATH"] = ""
if not (ROOT in os.environ["PYTHONPATH"].split(":")):
os.environ["PYTHONPATH"] = "%s:%s" % (os.environ["PYTHONPATH"], ROOT)
if not ROOT in sys.path:
sys.path.append(ROOT)
return f(*args, **kwargs)
return wrap
这是我如何使用它:
@patch_python_path
def initialize():
#at this point any code being run has access to local modules through relative imports
pass
这种方法是否存在我不知道的重大问题?
我的目标如下:
- 我想要一个用户可以立即使用的自包含引导程序,而无需任何额外的环境操作
- 我还假设用户可以更改引导程序包的名称,因此所有导入都必须保持相对
[编辑] 我实际上意识到我面临的问题更多地与 Fabric 运行任务的方式有关,而不是纯 Python 模块导入。如果我尝试从 python shell(而不是 fab task1)运行任务,则所有导入都可以正确解析,而无需任何修补。通过 fab 运行任务会导致导入错误