前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python循环引用中的原理

python循环引用中的原理

作者头像
超级大猪
发布2019-11-21 20:35:46
1.4K0
发布2019-11-21 20:35:46
举报
文章被收录于专栏:大猪的笔记大猪的笔记

Python循环引用是允许的,但在极端情况下仍然会挂挂。比如:

a.py

import sys
print("a,start")
for item in sys.modules:
    if item in ["a", "b"]:
        print(item)
from b import c
def start():
    pass

b.py

import sys
print("b start")
for item in sys.modules:
    if item in ["a", "b"]:
        print(item)

from a import start
def c():
    pass

结果:

a,start
b start
b
Traceback (most recent call last):
  File "E:/yinzihao/workspace/testpy/a.py", line 6, in <module>
    from b import c
  File "E:\yinzihao\workspace\testpy\b.py", line 7, in <module>
    from a import start
  File "E:\yinzihao\workspace\testpy\a.py", line 6, in <module>
    from b import c
ImportError: cannot import name 'c'
a,start
b
a

原理很简单,python中import module会执行以下几步:

1.检查sys.modules中是否有这个模块 2.如果没有,将sys.modules[module] = empty_pyc 3.执行module.py的所有代码,生成对应的pyc 4.sys.modules[module] = real_pyc

上面的例子中:

1.首先执行 a:from b import c 2.此时sys.modules中没有b(也没有a),跳转到b.py。将b 添加到sys.modules。 3.执行 b:from a import start 4.此时sys.modules中没有a,跳转到a.py,将a添加到sys.modules。此时,a,b都在sys.modules中。 5.程序再次执行到 a:from b import c此时sys.modules中包含b,所以,会直接尝试加载b.c,然而,b并没有执行完全,c是不存在的。

解决方案:

几乎所有的循环引用BUG都是直接使用from aa import bb造成的。使用import aa,再在代码中使用aa.bb可以避免大部分异常。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-07-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原理很简单,python中import module会执行以下几步:
  • 上面的例子中:
  • 解决方案:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档