在Python中重用代码的机制是导入模块(也即是import),对于该机制其内部的主要流程如下:
1)在系统内部的sys.modules中以模块名作为字符串进行查找,是否已经存在该模块,如果存在则直接返回;
2)当不存在时,则按照相应的文件搜索规则找到对应的py文件(其实还包括扩展等),编译为字节码;
3)在sys.modules中以模块名字符串为key添加一个新建模块对象,然后依序执行该模块文件中的代码,依次将生成的对象添加到模块对象中;
为了验证如上流程,我们设计如下代码作为模块进行导入。
"""
import测试,被导入文件
"""
import sys
print('"tobeimported" in sys.modules -->',"tobeimported" in sys.modules)
#被其他文件导入将输出 True,而单独执行本文件则为 False
import tobeimported
base = set(dir(sys.modules["tobeimported"]))
x = 1
print(set(dir(sys.modules["tobeimported"]))-base)
#执行代码时刻增加对象,执行结果应该为刚刚创建的 base 和 x
针对如上测试代码,如果在其他文件中导入该文件,则结果如下:
"tobeimported" in sys.modules --> True
{'x', 'base'}
如果单独执行本文件,则结果如下:
"tobeimported" in sys.modules --> False
"tobeimported" in sys.modules --> True
{'x', 'base'}
set()
对于上述结果,需要解释一下,在Python中执行当前文件时,其模块键值为 "__main__",因此其文件中的import文件会导致其执行两次,而第二次执行器对应的模块也不为 "tobeimported",故第二次相减的结果为空集,如果将代码中的 "tobeimported" 替换为 __name__,则两次结果均为 base 和 x,如下:
print('begin in module -->',__name__)
import sys
print(__name__,' in sys.modules -->',__name__ in sys.modules)
#被其他文件导入将输出 True,而单独执行本文件则为 False
import tobeimported
base = set(dir(sys.modules[__name__]))
x = 1
print(set(dir(sys.modules[__name__]))-base)
#执行代码时刻增加对象,执行结果应该为刚刚创建的 base 和 x
print('end in module -->',__name__)
执行结果:
begin in module --> __main__
__main__ in sys.modules --> True
begin in module --> tobeimported
tobeimported in sys.modules --> True
{'base', 'x'}
end in module --> tobeimported
{'base', 'x'}
end in module --> __main__
|