`importlib.reload` 不会替换模块的 `__dict__` 中的对象
`importlib.reload` does not replace the objects in the module's `__dict__`
运行 Python 3.7.9 在 python3.7-buster docker 容器上。
这是我的问题的一个基本示例
首先,我导入 json
模块并验证它包含 decoder
模块作为属性:
>>> import json, importlib
>>> json.decoder
<module 'json.decoder' from '/usr/local/lib/python3.7/json/decoder.py'>
然后,我将该属性设置为 None 并验证:
>>> json.__dict__['decoder'] = None
>>> json.decoder # None's repr is blank
然后我尝试重新加载模块并重新检查 json.decoder
的状态。我希望它将再次成为一个模块,但我发现的是:
>>> importlib.reload(json)
<module 'json' from '/usr/local/lib/python3.7/json/__init__.py'>
>>> json.decoder # None's repr is blank
好的,我可以直接导入解码器吗?不,它只是 returns 来自已加载模块的值。 (这并非完全出乎意料。)
>>> from json import decoder as new_decoder
>>> new_decoder # None's repr is blank
OK,我注意到importlib.reload()
returns一个模块。如果我将模块标识符设置为等于函数调用会怎样?
>>> json = importlib.reload(json)
>>> json.decoder # None's repr is blank
这是来自 the Python documentation on reload 的相关片段:
When reload() is executed:
Python module’s code is recompiled and the module-level code re-executed, defining a new set of
objects which are bound to names in the module’s dictionary by reusing the loader which originally
loaded the module. The init function of extension modules is not called a second time.
...
The names in the module namespace are updated to point to any new or changed objects
这似乎准确描述了我预期的行为,但不是我遇到的行为。
这是怎么回事?
重新执行 json
包的代码 不会 重新分配 json.decoder
。 json
包的 __init__.py
中没有任何东西可以做到这一点。
json
包的 __init__.py
包含以下行:
from .decoder import JSONDecoder, JSONDecodeError
这一行第一次是 运行(在 json
的第一次导入时),json.decoder
子模块被初始化,并且作为初始化的一部分,对那个的引用子模块设置为 json
模块对象的 decoder
属性。
当你重新加载json
时,这一行被重新执行,但是json.decoder
子模块已经初始化过了,不需要再次初始化。 json.decoder
未重新分配。
一般来说,您不应该指望通过重新加载模块来使其处于任何正常或有用的状态。模块重新加载有很多奇怪和微妙的问题,例如创建“邪恶的双胞胎”类,不更新从模块导入的任何东西from
,不能很好地与扩展模块一起使用,等等
运行 Python 3.7.9 在 python3.7-buster docker 容器上。
这是我的问题的一个基本示例
首先,我导入 json
模块并验证它包含 decoder
模块作为属性:
>>> import json, importlib
>>> json.decoder
<module 'json.decoder' from '/usr/local/lib/python3.7/json/decoder.py'>
然后,我将该属性设置为 None 并验证:
>>> json.__dict__['decoder'] = None
>>> json.decoder # None's repr is blank
然后我尝试重新加载模块并重新检查 json.decoder
的状态。我希望它将再次成为一个模块,但我发现的是:
>>> importlib.reload(json)
<module 'json' from '/usr/local/lib/python3.7/json/__init__.py'>
>>> json.decoder # None's repr is blank
好的,我可以直接导入解码器吗?不,它只是 returns 来自已加载模块的值。 (这并非完全出乎意料。)
>>> from json import decoder as new_decoder
>>> new_decoder # None's repr is blank
OK,我注意到importlib.reload()
returns一个模块。如果我将模块标识符设置为等于函数调用会怎样?
>>> json = importlib.reload(json)
>>> json.decoder # None's repr is blank
这是来自 the Python documentation on reload 的相关片段:
When reload() is executed:
Python module’s code is recompiled and the module-level code re-executed, defining a new set of objects which are bound to names in the module’s dictionary by reusing the loader which originally loaded the module. The init function of extension modules is not called a second time. ... The names in the module namespace are updated to point to any new or changed objects
这似乎准确描述了我预期的行为,但不是我遇到的行为。 这是怎么回事?
重新执行 json
包的代码 不会 重新分配 json.decoder
。 json
包的 __init__.py
中没有任何东西可以做到这一点。
json
包的 __init__.py
包含以下行:
from .decoder import JSONDecoder, JSONDecodeError
这一行第一次是 运行(在 json
的第一次导入时),json.decoder
子模块被初始化,并且作为初始化的一部分,对那个的引用子模块设置为 json
模块对象的 decoder
属性。
当你重新加载json
时,这一行被重新执行,但是json.decoder
子模块已经初始化过了,不需要再次初始化。 json.decoder
未重新分配。
一般来说,您不应该指望通过重新加载模块来使其处于任何正常或有用的状态。模块重新加载有很多奇怪和微妙的问题,例如创建“邪恶的双胞胎”类,不更新从模块导入的任何东西from
,不能很好地与扩展模块一起使用,等等