最近遇到这么一个问题,就是分词的jieba在我的工程里面logging的level设置无效。于是乎,我就去翻阅是不是这块儿引用出了问题。我就顺便学习一下python的import机制。
讲解
from B import D,Python内部会分成几个步骤:
- 在sys.modules中查找符号"B"
- 如果符号B存在,则获得符号B对应的module对象<module B>
- 从<module B>的dict中获得符号"D"对应的对象,如果"D"不存在,则抛出异常
- 如果符号B不存在,则创建一个新的module对象<module B>,注意,这时,module对象的dict为空
- 执行B.py中的表达式,填充<module B>的dict
- 从<module B>的dict中获得"D"对应的对象,如果"D"不存在,则抛出异常
例子
这块儿有个嵌套引用的例子,我觉得很经典,放在这里,做个记录。
#A.py
from B import D
class C:
pass
#B.py
from A import C
class D:
pass
运行A.py的时候,在python里面会这么运行:
- 执行A.py的第一行,发现sys.module里面没有<module B>,所以创建一个空的<module B>,放入sys.module,生成一个dict对象
- 导入B.py,填充<module B>
- 执行B.py的第一行,发现要导入<module A>, 然后再sys.module中查找<module A>
- 找到<module A>后,查找dict对象里的<Object C>,但是没有发现,引用错误
原因说白了就是class C还没有来得及建立,就请求C,肯定会出问题。如果想要执行正确,需要将B.py里面的 from A import C 改成 import A 就没有问题了。
这儿有一个比较直观的图片:
需要特别注意的是 Python只加载一次module,如果需要重新加载需要使用reload()。
至于我那个问题,随后再说吧。
网友评论