我正在研究这两个相关的问题:
here
和
here
.
我在Python 3.6中看到了一个我不期望的行为,这与使用plain的行为不同
reload
在Python 2.7(和3.4)中。也就是说,似乎在模块初始化期间或在重新加载期间重新执行模块时填充的模块属性在使用删除其本地名称后不会恢复
del
... 见下文:
对于Python 3.6:
In [1]: import importlib
In [2]: import math
In [3]: del math.cos
In [4]: math.cos
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-4-05b06e378197> in <module>()
----> 1 math.cos
AttributeError: module 'math' has no attribute 'cos'
In [5]: math = importlib.reload(math)
In [6]: math.cos
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-6-05b06e378197> in <module>()
----> 1 math.cos
AttributeError: module 'math' has no attribute 'cos'
In [7]: importlib.reload(math)
Out[7]: <module 'math' from '/home/ely/anaconda/envs/py36-keras/lib/python3.6/lib-dynload/math.cpython-36m-x86_64-linux-gnu.so'>
In [8]: math.cos
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-8-05b06e378197> in <module>()
----> 1 math.cos
AttributeError: module 'math' has no attribute 'cos'
对于Python 2.7(和
Python 3.4
):
In [1]: import math
In [2]: del math.cos
In [3]: math.cos
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-3-05b06e378197> in <module>()
----> 1 math.cos
AttributeError: 'module' object has no attribute 'cos'
In [4]: reload(math)
Out[4]: <module 'math' from '/home/ely/anaconda/lib/python2.7/lib-dynload/math.so'>
In [5]: math.cos
Out[5]: <function math.cos>
我试着从
source code
一直到
C-level module exec function
,我看不到任何逻辑会导致它无法写入重新初始化的
cos
属性返回到模块的模块作用域全局的dict中。
我怀疑这是C级重新执行逻辑中的某种类型的错误,它查看模块字典中找到的属性名称(以前导入时就存在的名称,可能会经过变异删除属性,如我的示例所示),然后使用
exec
要将模块的执行副作用写入该字典,需要跳过键名(如
余弦
)这与Python 2.7的行为不同,在模块的名称空间中不存在。