前一段时间,在猿编程讲师岗前培训中,有学员问到在pgzero里面,为什么 import pgzrun 之后,music、mouse、keyboard这些模块就能自动加载,不需要import,就能直接使用了。于是我看了一下源码,最核心的代码是这两句,摘录如下:
mod = sys.modules['__main__'] mod.__dict__.update(builtins.__dict__) # builtins 模块中引用了music等模块
以上代码中,有一个关键的方法,就是sys.modules。sys.modules是一个全局字典,该字典是python启动后就加载在内存中。当导入新的模块时,sys.modules都将记录这些模块。字典sys.modules对于加载模块起到了缓冲的作用。当某个模块第一次导入,字典sys.modules将自动记录该模块。当第二次再导入该模块时,python会直接到字典中查找,从而加快了程序运行的速度。
理解以上的解释之后,我们再看一个例子:
import sys mod = sys.modules['__main__'] mod.__dict__.update({'aa':'bb'}) print(aa) # 此处能输出bb
以上代码相当于把 aa:bb 这个键值对,添加到了sys模块中,而sys模块是提供对解释器使用或维护的一些变量的访问,像我们定义变量,其实也可以通过sys拿到,那么以上的 update 方法,等同于定义了变量aa='bb',所以打印aa可以得到bb的值。
接下来,我们再看一下如何实现模块自动加载,依次定义如下文件。
# main.py import sys import autoload mod = sys.modules['__main__'] mod.__dict__.update(autoload.__dict__) print(a.add(1,2)) # 输出3 print(b.div(1,2)) # 输出0.5
# autoload.py import a import b
# a.py def add(num1, num2): return num1 + num2
# b.py def div(num1, num2): return num1 / num2
以上例子中,main.py 只引入了 autoload 模块,而在 autoload 中引入a、b两个模块。因为 main.py 文件中有 mod.__dict__.update() 操作,从而实现了 a、b两个模块的自动加载,就这。
本文为 陈华 原创,欢迎转载,但请注明出处:http://edu.ichenhua.cn/read/214