在__init__.py和同一目录中导入模块时,python 2.7和3.3+之间的区别

kha*_*mel 8 python python-import flask python-3.x flask-security

最近我遇到了一个问题,即我在flask-security中使用信号在python 3.3中表现不如预期.在查看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
Run Code Online (Sandbox Code Playgroud)

我将进入Truepython 2.7,我将获得Falsepython 3.3+.

python 3.3+有什么不同导致导入行为的这种差异?

编辑: 我仍然由Python 2.7 VS 3.3+的问题难住了,但已成功地缩小了,当问题发生__init__.pyflask.ext被称为并使用ExtensionImporter类从exthook.py进口瓶的安全性.

在python 3.4下运行以下命令会在True直接导入flask-security时返回,避免使用扩展钩子:

from flask_security.signals import user_registered as user_reg_sig
from flask_security import user_registered
user_registered==user_reg_sig
Run Code Online (Sandbox Code Playgroud)

这里有关于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'>"
Run Code Online (Sandbox Code Playgroud)

sor*_*rin 0

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

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

主要是你必须假设这两个对象可能不同并解决这个问题。