重新加载Python模块 -reload的应用

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()fromimport

如果一个模块实例化了一个类的实例,重新加载定义该类的模块不会影响实例的方法定义——它们继续使用旧的类定义。对于派生类也是如此。

import os
import importlib
import Test
import time

filePrefix='Test'
fileSuffix='.py'

text =('import os
'
"import sys
"
"def demo():
")

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

转载请注明出处:https://www.cnblogs.com/lei-zi/
原文地址:https://www.cnblogs.com/lei-zi/p/15479787.html