我知道在 Python 中存在很多关于相同导入问题的问题,但似乎没有人能够提供正确用法的清晰示例。
假设我们有一个包mypackage
有两个模块foo
and bar
。里面foo
我们需要能够访问bar
.
因为我们还在开发中,mypackage
不在sys.path
.
我们希望能够:
- import
mypackage.foo
- run
foo.py
作为脚本并执行示例用法或测试__main__
部分。
- 使用Python 2.5
我们必须如何在 foo.py 中进行导入才能确保它在所有这些情况下都能工作。
# mypackage/__init__.py
...
# mypackage/foo/__init__.py
...
# mypackage/bar.py
def doBar()
print("doBar")
# mypackage/foo/foo.py
import bar # Fails with module not found
import .bar # Fails due to ValueError: Attempted relative import in non-package
def doFoo():
print(doBar())
if __name__ == '__main__':
doFoo()
看看下面的信息来自PEP 328 http://www.python.org/dev/peps/pep-0328/#relative-imports-and-name:
相对导入使用模块的__name__
属性来确定该模块在包层次结构中的位置。如果模块的名称不包含任何包信息(例如,它被设置为'__main__'
)然后相对导入将被解析,就像该模块是顶级模块一样,无论该模块实际位于文件系统上的位置。
当你跑步时foo.py
作为脚本,该模块的__name__
is '__main__'
,所以你不能进行相对导入。即使mypackage
was on sys.path
。基本上,如果导入了某个模块,则只能从该模块进行相对导入。
以下是解决此问题的几个选项:
1) In foo.py
,检查是否__name__ == '__main__'
并有条件地添加mypackage
to sys.path
:
if __name__ == '__main__':
import os, sys
# get an absolute path to the directory that contains mypackage
foo_dir = os.path.dirname(os.path.join(os.getcwd(), __file__))
sys.path.append(os.path.normpath(os.path.join(foo_dir, '..', '..')))
from mypackage import bar
else:
from .. import bar
2)始终导入bar
using from mypackage import bar
,并执行foo.py
以这样的方式mypackage
自动可见:
$ cd <path containing mypackage>
$ python -m mypackage.foo.foo
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)