首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在Python模块中正确使用相对或绝对导入?

如何在Python模块中正确使用相对或绝对导入?
EN

Stack Overflow用户
提问于 2010-09-01 18:11:39
回答 5查看 23.3K关注 0票数 26

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

代码语言:javascript
代码运行次数:0
运行
复制
# /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)一起工作的解决方案。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-09-06 06:44:53

首先,我假设您知道您所编写的代码会导致循环导入问题,因为foo导入bar,反之亦然;尝试添加

代码语言:javascript
代码运行次数:0
运行
复制
from foo import bar

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

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

一个可能的建议是:

foo.py

代码语言:javascript
代码运行次数:0
运行
复制
try:
    from . import bar
except ValueError:
    import bar

if __name__ == "__main__":
    pass

bar.py:

代码语言:javascript
代码运行次数:0
运行
复制
if __name__ == "__main__":
    pass

顺便说一句,从合适的位置调用脚本通常要好得多。

代码语言:javascript
代码运行次数:0
运行
复制
python -m foo.bar

可能是最好的方法。这个runs the module as a script

票数 16
EN

Stack Overflow用户

发布于 2010-09-01 20:23:36

你可以以一种不同的方式开始“作为独立的模块运行”:

而不是:

代码语言:javascript
代码运行次数:0
运行
复制
python foo/bar.py

使用:

代码语言:javascript
代码运行次数:0
运行
复制
python -mfoo.bar

当然,foo/__init__.py文件必须存在。

还请注意,你在foo.pybar.py之间有一个循环依赖--这是行不通的。我想这只是你例子中的一个错误。

更新:将它用作foo/bar.py的第一行似乎也很好用

代码语言:javascript
代码运行次数:0
运行
复制
#!/usr/bin/python -mfoo.bar

然后,您可以直接在POSIX系统中执行该脚本。

票数 22
EN

Stack Overflow用户

发布于 2011-02-12 15:43:42

每个文件夹中都需要__init__.py

仅当执行以下操作时,相对导入才有效:

代码语言:javascript
代码运行次数:0
运行
复制
python test.py

test.py导入foo.py和foo.py可以相对导入test.py及以上文件夹中的任何内容。

你不能这样做:

代码语言:javascript
代码运行次数:0
运行
复制
cd foo
python foo.py
python bar.py

它永远不会起作用。

您可以尝试使用sys.path.append或sys.path.insert解决方案,但是这样会弄乱路径,并且f=open(文件名)也会出现问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3616952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档