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

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

问题描述

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

#/test.py: 只是一个导入 foo 模块的示例文件进口富...#/foo/foo.py:从 .进口酒吧...如果 __name__ == "__main__":经过#/foo/bar.py: foo 的子模块,由 foo.py 使用从 .进口富...如果 __name__ == "__main__":经过

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

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

解决方案

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

from foo 导入栏

到test.py,你会看到它失败了.必须更改示例才能工作.

所以,你真正要问的是当相对导入失败时回退到绝对导入;实际上,如果您将 foo.py 或 bar.py 作为主模块执行,则其他模块将位于根级别,如果它们与系统上的另一个模块共享名称,则取决于哪个模块sys.path 中的顺序.由于当前目录通常是第一个,如果可用,将选择本地模块 - 即,如果您在当前工作目录中有一个 'os.py' 文件,它将被选择而不是内置的.

一个可能的建议是:

foo.py

尝试:从 .进口酒吧除了值错误:进口酒吧如果 __name__ == "__main__":经过

bar.py:

if __name__ == "__main__":经过

顺便说一下,从适当的位置调用脚本通常方式更好.

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天全站免登陆