相对进口不起作用,看起来无法找到模块

时间:2015-02-11 16:06:41

标签: python python-3.x

我有以下情况,其中 a 是一个目录:

a/
  __init__.py
  first.py
  second.py

__初始化__。PY

print('i\'m starting the directory')
__all__ = ['second', 'first']

first.py

print('hi, i\'m the first')
from . import *

second.py

print('hi, i\'m the second')

所以当我从交互式提示符运行时:

>>> import a.first
i'm starting the directory
hi, i'm the first
hi, i'm the second
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/antox/Scrivania/a/first.py", line 2, in <module>
    from . import *
AttributeError: 'module' object has no attribute 'first'

为什么找不到 first.py 模块?我的意思是我希望没有错误;在导入运行期间,我认为可以看到 first.py 已经加载,因此没有错误,它只是跳到__all__中列出的下一个。

1 个答案:

答案 0 :(得分:3)

这似乎是Python导入机制中一个长期存在的错误。问题是a模块在完全加载之后才会添加到其包的全局命名空间中。如果from package import module仅部分加载,则会中断module语句。你仍然可以使用import package.module,但很长一段时间都有来自导入系统的特殊支持。

正如jonrsharpe所述,Python开发人员已经意识到了这个问题since 2004。由于只有在包含模块的循环导入时出现问题,并且循环导入通常被认为是不好的设计,因此他们没有把重点放在修复它上面。

然而,最近有进展!几个月前添加了A partial fix,用于Python 3.5,它刚刚发布了第一个alpha版本(完整版本定于9月发布)。该修补程序在加载时仍然不会module实际添加package,而是对from package import module语句添加额外的检查,以便它们无论如何都能在以前引发的循环导入情况下工作ImportError

但这并不能解决from package import *案例。通配符导入的代码显然仍然希望package.__all__中的所有名称实际存在于模块本身中。它似乎没有检查sys.modules字典以检查仍在加载过程中的模块。

那么,这对您的代码意味着什么?我认为有两个重要的教训:首先,如果你可以帮助它,不要使用循环导入(而是尝试将两个模块中的一些代码分解为第三个实用程序模块)。其次,不要使用通配符导入(如果使用first.py from . import first, second,则在Python 3.5中没有错误。)