Python 2.7和3.3+在从同一目录导入__init__.py和模块时的区别

8

最近我遇到了一个问题,即在Python 3.3中,我使用的来自flask-security的信号表现不如预期。查看flask-security的源代码时,我注意到我从flask-security包中的模块导入的信号也在__init__.py中被导入。通过从包的顶层导入信号,我能够解决我的问题(因为当初始化包时,信号会被导入)。

如果我运行以下代码:

from flask.ext.security import user_registered
from flask.ext.security.signals import user_registered as user_reg_sig
user_registered==user_reg_sig

在Python 2.7中,我会得到True,而在Python 3.3+中,我会得到False。在Python 3.3+中有什么不同导致了这种导入行为的差异?
编辑:我仍然被Python 2.7和3.3+的问题所困扰,但已经成功缩小了范围,发现当调用flask.ext的__init__.py并使用exthook.py中的ExtensionImporter类导入flask-security时,出现了问题。
在Python 3.4下运行以下代码可直接导入flask-security避免扩展钩子,并返回True
from flask_security.signals import user_registered as user_reg_sig
from flask_security import user_registered
user_registered==user_reg_sig

这里是针对flask.ext.security和flask_security示例的信号repr():
from flask_security.signals import user_registered as user_reg_sig
from flask_security import user_registered

repr(user_registered)
>>> "<blinker.base.NamedSignal object at 0x7fb38e258400; 'user-registered'>"

repr(user_reg_sig)
>>> "<blinker.base.NamedSignal object at 0x7fb38e258400; 'user-registered'>"

from flask.ext.security import user_registered
from flask.ext.security.signals import user_registered as user_reg_sig

repr(user_registered)
>>> "<blinker.base.NamedSignal object at 0x7fb38e258400; 'user-registered'>"

repr(user_reg_sig)
>>> "<blinker.base.NamedSignal object at 0x7fb38dd030b8; 'user-registered'>"

如果你打印出每个的repr呢? - Ignacio Vazquez-Abrams
在问题中添加了repr。因此,通过flask.ext访问时肯定是不同的对象。 - khammel
我猜这与[https://dev59.com/0m445IYBdhLWcg3wkLFG]有关,以及Python3.3在该领域的变化。还阅读了此[http://python-notes.curiousefficiency.org/en/latest/python_concepts/import_traps.html]。 - mkiever
1个回答

0

在多种情况下,当您重新导入模块时,Python 可能会决定创建一个对象的新实例。

事实上,这甚至不是 Python 3 特有的,它可能发生在各种场景中。

主要是您必须假设这两个对象可能不同,并围绕此进行工作。


谢谢。似乎 Flask 在使用信号时存在一些问题,当通过 flask.ext.* 进行导入时会发生什么。 - khammel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接