@spiritnotes
2016-02-18T04:36:46.000000Z
字数 1818
阅读 1442
Python
在Python中重用代码的机制是导入模块(也即是import),对于该机制其内部的主要流程如下:
为了验证如上流程,我们设计如下代码作为模块进行导入,被用于导入的文件为tobeimported.py,代码如下:
import sys
print('"tobeimported" in sys.modules -->',"tobeimported" in sys.modules)
#被其他文件导入将输出 True,而单独执行本文件则为 False
#import tobeimported 测试2,3中添加
base = set(dir(sys.modules["tobeimported"]))
x = 1
print(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 sys
print(__name__,' in sys.modules -->',__name__ in sys.modules)
import tobeimported
base = set(dir(sys.modules[__name__]))
x = 1
print(set(dir(sys.modules[__name__]))-base)
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__
通过上面的分析,看下面的代码:
# a.py
import b
def f():
return b.x
f()
# b.py
import a
x = 1
def g():
return a.f()
如果我们直接导入a,可以发现一切正常,虽然b中也引用了a.f,但其位于函数内,导入的时候并不会执行;而导入b,则会由于b中执行import a时会调用f()导致其会引用到b.x,而此时b.x还没有定义,出现异常。