Python 相对导入在包内而不是在路径上

Fin*_*inn 5 python packaging pythonpath

如何将 python 包中的父目录(不在路径上)中的文件导入到子目录中的文件中?

我不太清楚 python 打包的词汇,所以举个例子:

dir1/
    __init__.py
    runner.py
    in_dir1.py
    dir2/
        __init__.py
        in_dir2.py
Run Code Online (Sandbox Code Playgroud)

dir1/in_dir1.py:

def example():
    print "Hello from dir1/in_dir1.example()"
Run Code Online (Sandbox Code Playgroud)

dir1/dir2/in_dir2.py

import in_dir1   #or whatever this should be to make this work
print "Inside in_dir2.py, calling in_dir1.example()"
print in_dir1.example()
Run Code Online (Sandbox Code Playgroud)

鉴于它dir1不在 python 路径上,我正在寻找导入in_dir1in_dir2.

我尝试from .. import in_dir1from ..dir1 import in_dir1 基于此问答,但都不起作用。执行该意图的正确方法是什么?这个问答似乎包含了答案;但是,我不太确定该怎么做/如何使用PEP 366实际解决我的问题

两个__init__.py文件都是空的,我使用的是v2.6

我试图在不使用谷歌不断出现的任何路径黑客的情况下做到这一点。

Rob*_*ers 3

答案在您给出的链接中:

相对导入使用模块的 __name__ 属性来确定该模块在包层次结构中的位置。如果模块的名称不包含任何包信息(例如,将其设置为“ main ”),则将解析相对导入,就好像该模块是顶级模块一样,无论该模块实际位于文件系统上的位置。

您不能在脚本中进行相对导入__main__(即如果您直接运行python in_dir2.py)。

为了解决这个问题,PEP 366 允许你做的是设置全局__package__

import dir1
if __name__ == '__main__':
    __package__ = 'dir1.dir2'
    from .. import in_dir1
Run Code Online (Sandbox Code Playgroud)

请注意,包裹dir1仍然必须打开sys.path!您可以通过操纵sys.path来实现此目的。但到那时,你在绝对进口方面取得了什么成就?

  • @Finn,这是一种边缘情况,因为您直接运行包的子模块。虽然正确的方法是创建一个单独的脚本来导入包/子模块并运行它。 (2认同)