@spiritnotes
2016-02-18T04:36:46.000000Z
字数 1818
阅读 1595
Python在Python中重用代码的机制是导入模块(也即是import),对于该机制其内部的主要流程如下:
为了验证如上流程,我们设计如下代码作为模块进行导入,被用于导入的文件为tobeimported.py,代码如下:
import sysprint('"tobeimported" in sys.modules -->',"tobeimported" in sys.modules)#被其他文件导入将输出 True,而单独执行本文件则为 False#import tobeimported 测试2,3中添加base = set(dir(sys.modules["tobeimported"]))x = 1print(set(dir(sys.modules["tobeimported"]))-base)#执行代码时刻增加对象,执行结果应该为刚刚创建的 base 和 x
针对如上测试代码,如果在其他文件中导入该模块文件,则结果如下:
"tobeimported" in sys.modules --> True #说明最先是赋值sys.modules['tobeimported']{'x', 'base'} #说明模块对象可变,代码执行时改变模块对象
如果在测试1的代码中添加如下代码(随处)使其被导入,可见其对结果没有任何变化。
import tobeimported
如果单独执行被导入文件,则结果如下:
"tobeimported" in sys.modules --> False"tobeimported" in sys.modules --> True{'x', 'base'}set()
可见tobeimported.py中代码被执行了2次。这里的原因是由于执行当前文件,sys.modules仍然会添加一个模块,其模块键值为 "__main__",因此当执行“import tobeimported”语句时,会重新执行一下本文件。
在测试3的基础上,将代码中的 "tobeimported" 替换为 __name__,则两次结果均为 base 和 x,如下:
print('begin in module -->',__name__)import sysprint(__name__,' in sys.modules -->',__name__ in sys.modules)import tobeimportedbase = set(dir(sys.modules[__name__]))x = 1print(set(dir(sys.modules[__name__]))-base)print('end in module -->',__name__)
执行结果:
begin in module --> __main____main__ in sys.modules --> Truebegin in module --> tobeimportedtobeimported in sys.modules --> True{'base', 'x'}end in module --> tobeimported{'base', 'x'}end in module --> __main__
通过上面的分析,看下面的代码:
# a.pyimport bdef f():return b.xf()# b.pyimport ax = 1def g():return a.f()
如果我们直接导入a,可以发现一切正常,虽然b中也引用了a.f,但其位于函数内,导入的时候并不会执行;而导入b,则会由于b中执行import a时会调用f()导致其会引用到b.x,而此时b.x还没有定义,出现异常。
