python循环引用中的原理

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可以避免大部分异常。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Crossin的编程教室

用python写一个简单的贪吃蛇游戏

Python 虽然并不是一个“为游戏而生”的语言,但也有着自己的游戏引擎。最常用的就是 pygame。另外还有一个知名游戏引擎 cocos2d,它的最初版本就是...

15810
来自专栏TeamsSix的网络空间安全专栏

Python Threading 学习笔记 | 5、不一定有效率GIL

GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定。

7140
来自专栏Python爬虫与数据挖掘

Python小工具:3秒钟将视频转换为音频

最近,有读者微信上私聊我,想让我写一篇视频批量转换成音频的文章,我答应了,周末宅家里把这个小工具做出来了。

14110
来自专栏cwl_Java

ElasticSearch(7.2.2)-常⻅的字段类型

7520
来自专栏机器之心

四种高性能数据类型,Python collections助你优化代码、简洁任务

Python 的最大优势之一就是它有各种各样的模块和软件包可供选择。这些模块和包将 Python 的功能扩展到了许多流行领域,包括机器学习、数据科学、Web 开...

6320
来自专栏java思维导图

Java 中的 String 真的是不可变吗?

我们都知道 Java 中的 String 类的设计是不可变的,来看下 String 类的源码。

7820
来自专栏Python疯子

pyecharts的V1.5绘画优美地图<一>

​版本: pyecharts 分为 v0.5.X 和 v1 两个大版本,v0.5.X 和 v1 间不兼容,v1 是一个全新的版本

21610
来自专栏机器之心

从Python代码到APP,你只需要一个小工具:GitHub已超3000星

GitHub地址:https://github.com/streamlit/streamlit/

13730
来自专栏猴子聊数据分析

如何学习和评价《利用python进行数据分析》这本书?

​这本书几乎是数据分析入门必读书了。主要介绍了python3个库numpy(数组),pandas(数据分析)和matplotlib(绘图)的学习。

10420
来自专栏HACK学习

一个5K RMB奖励的SRC漏洞

在挖一些SRC漏洞的时候需要时刻保持敏感的状态,特别是在企业上线新业务,或者一些新漏洞爆发的时候,这些新漏洞可能是官方都未提供补丁的0day,或者刚被公布细节的...

12220

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励