python 2.5中的相对导入 [英] Relative imports in python 2.5

查看:100
本文介绍了python 2.5中的相对导入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道在Python中有很多关于相同导入问题的问题,但是似乎没有人能够提供正确用法的清晰示例.

I know that there are lots of questions about the same import issues in Python but it seems that nobody managed to provide a clear example of correct usage.

假设我们有一个包含两个模块foobar的软件包mypackage.在foo内部,我们需要能够访问bar.

Let's say that we have a package mypackage with two modules foo and bar. Inside foo we need to be able to access bar.

由于我们仍在开发中,因此mypackage不在sys.path中.

Because we are still developing it, mypackage is not in sys.path.

我们希望能够:

  • 导入mypackage.foo
  • foo.py作为脚本运行,并从__main__部分执行示例用法或测试.
  • 使用Python 2.5
  • import mypackage.foo
  • run foo.py as a script and execute the sample usage or tests from the __main__ section.
  • use Python 2.5

我们必须在foo.py中执行导入操作,以确保在所有这些情况下都能正常工作.

How do we have to do the import in foo.py in order to be sure it will work in all these cases.

# 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()

推荐答案

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

Relative imports use a module's __name__ attribute to determine that module's position in the package hierarchy. If the module's name does not contain any package information (e.g. it is set to '__main__') then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.

当您将foo.py作为脚本运行时,该模块的__name__'__main__',因此您无法进行相对导入.即使mypackagesys.path上也是如此.基本上,只有从模块导入了模块,您才可以进行相对导入.

When you run foo.py as a script, that module's __name__ is '__main__', so you cannot do relative imports. This would be true even if mypackage was on sys.path. Basically, you can only do relative imports from a module if that module was imported.

以下是解决此问题的几种选择:

Here are a couple of options for working around this:

1)在foo.py中,检查是否__name__ == '__main__'并有条件地将mypackage添加到sys.path:

1) In foo.py, check if __name__ == '__main__' and conditionally add 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)始终使用from mypackage import bar导入bar,并以自动显示mypackage的方式执行foo.py:

2) Always import bar using from mypackage import bar, and execute foo.py in such a way that mypackage is visible automatically:

$ cd <path containing mypackage>
$ python -m mypackage.foo.foo

这篇关于python 2.5中的相对导入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆