如何在Python模块中正确使用相对或绝对导入? [英] How to properly use relative or absolute imports in Python modules?

查看:91
本文介绍了如何在Python模块中正确使用相对或绝对导入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Python中使用相对导入有一个缺点,您将无法再以独立方式运行模块,因为您将得到异常:ValueError: Attempted relative import in non-package

# /test.py: just a sample file importing foo module
import foo
...

# /foo/foo.py:
from . import bar
...
if __name__ == "__main__":
   pass

# /foo/bar.py: a submodule of foo, used by foo.py
from . import foo
...
if __name__ == "__main__":
   pass

我应该如何修改示例代码才能执行所有内容:test.pyfoo.pybar.py

我正在寻找一种适用于python 2.6+(包括3.x)的解决方案.

解决方案

首先,我假设您意识到您编写的内容将导致循环导入问题,因为foo导入bar,反之亦然;尝试添加

from foo import bar

到test.py,您将看到它失败.必须更改示例才能正常工作.

因此,您要问的是,当相对导入失败时,回退到绝对导入.实际上,如果您将foo.py或bar.py作为主要模块执行,则其他模块将仅位于根级别,并且它们是否与系统上要选择的其他模块共享名称取决于该模块. sys.path中的顺序.由于当前目录通常是第一个,因此将选择本地模块(如果有)-即,如果当前工作目录中有一个"os.py"文件,则将选择它而不是内置目录.

可能的建议是:

foo.py

try:
    from . import bar
except ValueError:
    import bar

if __name__ == "__main__":
    pass

bar.py:

if __name__ == "__main__":
    pass

从正确的位置调用脚本通常会更好.

python -m foo.bar

可能是最好的方法.此将模块作为脚本运行.

Usage of relative imports in Python has one drawback, you will not be able to run the modules as standalones anymore because you will get an exception: ValueError: Attempted relative import in non-package

# /test.py: just a sample file importing foo module
import foo
...

# /foo/foo.py:
from . import bar
...
if __name__ == "__main__":
   pass

# /foo/bar.py: a submodule of foo, used by foo.py
from . import foo
...
if __name__ == "__main__":
   pass

How should I modify the sample code in order to be able to execute all: test.py, foo.py and bar.py

I'm looking for a solution that works with python 2.6+ (including 3.x).

解决方案

First, I assume you realize what you've written would lead to a circular import issue, because foo imports bar and viceversa; try adding

from foo import bar

to test.py, and you'll see it fails. The example must be changed in order to work.

So, what you're asking is really to fallback to absolute import when relative import fails; in fact, if you're executing foo.py or bar.py as the main module, the other modules will just lie at the root level, and if they share the name with another module on the system which one will be picked depends on the order in sys.path. Since the current dir is usually the first, local modules will be picked if available - i.e., if you've got an 'os.py' file in the current working dir, it'll be picked instead of the builtin one.

A possibile suggestion is:

foo.py

try:
    from . import bar
except ValueError:
    import bar

if __name__ == "__main__":
    pass

bar.py:

if __name__ == "__main__":
    pass

By the way calling scripts from the proper position is usually way better.

python -m foo.bar

Is probably the best way to go. This runs the module as a script.

这篇关于如何在Python模块中正确使用相对或绝对导入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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