模块加载
模块加载时,主要完成以下动作:
- 在当前模块中加载由
import yy
或者from xx import yy
导入的未被其他模块导入过的模块; - 对模块中的类或者函数定义进行语法检查(ps:检查类属性和成员函数,不检查函数体),创建类定义对象和函数定义对象;
- 执行模块中的外层语句;
- 将类定义对象、函数定义对象和模块内的对象输出到该模块对应的二进制文件(.pyc为后缀的模块文件)。
注:输出到二进制文件有以下两个好处
- 避免模块被重复加载;
- 多次运行程序,若模块未变化,将不再做语法检查,也不创建模块二进制文件,直接从二进制文件中获取模块内的对象,提高运行效率。
非重复导入模块
base.py文件
print("module name:", __name__)
demo.py文件
import base
print("module name:", __name__)
main.py文件
import base
print("after import:", base.__name__)
print("-"*30)
import demo
print("after import:", demo.__name__)
print("-"*30)
if __name__ == "__main__":
print("run", __name__)
代码输出:
module name: base
after import: base
------------------------------
module name: demo
after import: demo
------------------------------
run __main__
base
模块被demo
和main
都使用import
导入,从代码输出可以看出,base
仅被导入一次。同时,运行过上述代码的童鞋已经看到,在同级目录下已经生成两个模块base
和demo
相应的.pyc为后缀的二进制文件。
类定义对象和函数定义对象
demo.py文件
class Demo(object):
a = 10
print("class define")
def show(self):
xxx # 此处有语法错误,模块导入时不检查
print("a =", self.a)
main.py文件
import demo
print("after import:", demo.__name__)
print("-"*30)
if __name__ == "__main__":
demo = demo.Demo()
demo.show()
代码输出:
class define
after import: demo
------------------------------
Traceback (most recent call last):
File "main.py", line 8, in <module>
demo.show()
File "demo.py", line 6, in show
xxx
NameError: name 'xxx' is not defined
从代码输出可以看出,main
中已经完成demo
导入,但未检查语法错误,仅仅在执行函数时才检查了语法。
模块外层语句
demo.py
print("module name:", __name__) # 外层语句
color_func = {} # 外层语句
def register(factory):
print("register in")
color, func = factory()
color_func[color] = func
print("register out")
def red_func():
print("call red_func")
@register # 外层语句,是一个装饰器,等价于调用:register(reg_red)
def reg_red():
print("reg_red")
return "red", red_func
print("*"*30) # 外层语句
color_func["red"]() # 外层语句
代码输出:
module name: demo
register in
reg_red
register out
******************************
call red_func
------------------------------
after import: demo