-
3.3 版中的新功能。
-
importlib.
reload
(模块) -
重新加载以前导入的模块。参数必须是一个模块对象,所以它必须之前已经成功导入。如果您使用外部编辑器编辑了模块源文件并希望在不离开 Python 解释器的情况下试用新版本,这将非常有用。返回值是模块对象(如果重新导入导致将不同的对象放入 中,则可能会有所不同
sys.modules
)。什么时候执行:
reload()
-
Python 模块的代码被重新编译并重新执行模块级代码,通过重用最初加载模块的加载器来定义一组新的对象,这些对象绑定到模块字典中的名称。
init
扩展模块的功能不会被第二次调用。 -
与 Python 中的所有其他对象一样,旧对象仅在其引用计数降至零后才会被回收。
-
模块命名空间中的名称更新为指向任何新的或更改的对象。
-
对旧对象的其他引用(例如模块外部的名称)不会重新引用到新对象,并且如果需要,必须在它们出现的每个命名空间中更新。
还有一些其他注意事项:
当一个模块被重新加载时,它的字典(包含模块的全局变量)被保留。名称的重新定义将覆盖旧定义,因此这通常不是问题。如果模块的新版本未定义由旧版本定义的名称,则旧定义保留。如果模块维护全局表或对象缓存,则此功能可用于模块的优势 - 使用
try
语句可以测试表的存在并在需要时跳过其初始化:try: cache except NameError: cache = {}
重新加载内置或动态加载的模块通常不是很有用。 刷新ING
sys
,__main__
,builtins
不建议和其他关键模块。在许多情况下,扩展模块不会被设计为多次初始化,并且在重新加载时可能会以任意方式失败。如果一个模块使用
from
…… 从另一个模块导入对象import
,调用另一个模块不会重新定义从它导入的对象——解决这个问题的一种方法是重新执行语句,另一种方法是使用 限定名称(module.name)反而。reload()
from
import
如果一个模块实例化了一个类的实例,重新加载定义该类的模块不会影响实例的方法定义——它们继续使用旧的类定义。对于派生类也是如此。
-
import os import importlib import Test import time filePrefix='Test' fileSuffix='.py' text =('import os\n' "import sys\n" "def demo():\n") for i in range(6): text1 = text +" print(" + str(i+1) + ")" filename=filePrefix+fileSuffix with open(filename,'w') as f: f.write(text1) f.closed importlib.reload(Test) time.sleep(1) Test.demo()
问题importlib.reload前需要加一定的延时(示例程序中延时不得小于1秒)
参考:https://docs.python.org/3.6/library/importlib.html?highlight=importlib%20reload#importlib.reload