1. 走向毁灭的函数循环调用

如果多个函数相互调用,构成闭环,就形成了函数的循环调用。下面的例子中,函数a在其函数体中调用了函数b,而函数b在其函数体中又调用了函数a,这就是典型的函数循环调用。

此种情况下,调用函数(无论是a函数还是b函数),会发生什么呢?

很快你就会发现,运行出现了问题,系统连续抛出异常,大约滚动了几千行之后,终于结束了运行。最后的提示是:RecursionError: maximum recursion depth exceeded while pickling an object

意思是说,发生了递归错误,在序列化(pickle)对象时超过了最大递归深度。

原来,循环调用类似于递归调用,为了保护堆栈不会溢出,Python环境一般都会设置递归深度保护,一旦查过递归深度,就会抛出递归错误,然后再一层一层退出堆栈。这就是屏幕滚动几千条错误信息的原因。

关于Python环境递归深度,可以通过sys模块查看和设置。

2. 同生共死的对象循环引用

函数的循环调用不难理解,而对象的循环引用就有点费解了。什么是对象的循环引用呢?当一个对象被创建时(比如实例化一个类),Python会为这个对象设置一个引用计数器。如果这个对象被引用,比如被关联到一个变量名,则该对象的引用计数器加1,如果关联关系取消,则该对象的引用计数器减1。当一个对象的引用计数器为1时(关于这一点,仅凭个人观察得出,未见权威说法),系统将自动回收该对象。这就是Python的垃圾回收机制。下面的代码,借助于sys模块,可以直观地看到一个列表对象的引用计数器的变化。

当多个对象存在相互间的成员引用,一旦形成闭环的时候,就会发生所谓对象的循环引用。我们来看一个例子:a和b是类A的两个实例对象,del这两个对象的时候,将会调用对象的__del__方法,最后显示“运行结束”。

运行结果正如我们所希望的那样。a: initb: inita: delb: del运行结束

然而,当我们创建了实例a和b之后,如果将a.somebody指向b,将b.somebody指向a,那么就产生了实例间成员相互引用形成闭环的情况。

运行这段代码,你会发现,del这两个对象的时候,对象的__del__方法并没有被立即执行,而是程序结束之后才被执行的。a: initb: init运行结束a: delb: del

这意味着,在程序运行期间,应该被回收的内存并没有正确回收。这样的问题,属于内存泄漏,应该给予高度重视。通常,我们可以使用gc模块强制回收内存。

再看运行结果,一切正常了。a: initb: inita: delb: del运行结束

3. 转圈推磨的模块循环导入

相对而言,模块的循环导入的情况一般极少发生。如果发生,一定是模块的功能分割不合理造成的,通过调整模块的定义,可以很容地解决问题。下面用一个最精简的例子,来演示一下模块循环导入是如何产生的。

名为a.py的脚本文件内容如下:

名为b.py的脚本文件内容如下:

两个脚本互相引用,并且各自使用了对方定义的常量MODULE_NAME。无论我们运行哪个脚本,都会因为模块的循环导入而无法正确执行。Traceback (most recent call last):File “a.py”, line 1, inimport bFile “D:\temp\csdn\b.py”, line 1, inimport aFile “D:\temp\csdn\a.py”, line 4, inprint(b.MODULE_NAME)AttributeError: module ‘b’ has no attribute ‘MODULE_NAME’

python循环引用是什么_细说Python的循环调用、循环引用和循环导入相关推荐

  1. python象棋棋盘麦粒问题_从零开始学习PYTHON3讲义(五)while循环和棋盘麦粒问题...

    <从零开始PYTHON3>第五讲 ​上一节课重点学习了字符串,并且传递了一个重要的理念,就是程序要对开发人员自己和用户都足够友好.在这个过程中,利用字符串给出充分.完整.准确的提示是非常重 ...

  2. python基础教程读书笔记_《Python基础教程》 读书笔记 第五章(下)循环语句

    导读热词 5.5.1while循环 x=1 while x<=100: print x x+=1 确保用户输入了名字: name="" while not name: nam ...

  3. python做审计底稿视频_最新Python教学视频,每天自学俩小时,让你offer拿到手软...

    2020最新Python零基础到精通资料教材,干货分享,新基础Python教材,看这里,这里有你想要的所有资源哦,最强笔记,教你怎么入门提升!让你对自己更加有信心,重点是资料都是免费的,免费!!! 如 ...

  4. python中类似对象吗_在Python中,两个对象什么时候相同? - python

    似乎2 is 2和3 is 3在python中始终为true,通常,对整数的任何引用都与对相同整数的任何其他引用相同. None(即None is None)也是如此.我知道用户定义类型或可变类型不会 ...

  5. python内存管理和释放_《python解释器源码剖析》第17章--python的内存管理与垃圾回收...

    17.0 序 内存管理,对于python这样的动态语言是至关重要的一部分,它在很大程度上决定了python的执行效率,因为在python的运行中会创建和销毁大量的对象,这些都设计内存的管理.同理pyt ...

  6. python中content的用法_学python吗,教你5个python现学现用的有趣用法

    在我们使用python的过程中也会遇到一些有意思的用法,这里找到了一些总结有趣的 话不多说,接着看下去吧!!!!python高薪就业(视频.学习路线.免费获取)​shimo.im for-else用法 ...

  7. python中的递归思想_〖Python〗-- 递归、面向对象初识及编程思想

    [递归.面向对象初识及编程思想] 一.递归 1.定义: 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. (1)递归就是在过程或函数里调用自身: (2)在使用递归策 ...

  8. python怎么做软件程序_看 Python 超级程序员使用什么开发工具

    Python超级程序员使用的开发工具 我以个人的身份采访了几个顶尖的Python程序员,问了他们以下5个简单的问题: 当前你的主要开发任务是什么? 你在项目中使用的电脑是怎样的? 你使用什么IDE开发 ...

  9. python编程第5版_正版 Python学习手册(原书第5版) python编程从入门到精通 python入门 计算机网络...

    上册 前言1 部分使用入门 章问答环节21 人们为何使用Python21 软件质量22 开发者效率23 Python是一门"脚本语言"吗23 好吧,Python的缺点是什么25 如 ...

最新文章

  1. VS2017配置OpenCV3.2+contrib3.2
  2. 创业者必看:创业得出的10条血泪经验
  3. 中兴5250交换机配置手册_TSN工业交换机中文说明
  4. 在Ubuntu下创建hadoop组和hadoop用户
  5. Java 接口编程题
  6. html计算一个数组所有元素的和,函数bsxfun,两个数组间元素逐个计算的二值操作...
  7. 博客,跳出日志的围墙[转]
  8. Win10点击声音图标打不开音量调节的解决方法
  9. 在阿里云注册域名后如何网站备案
  10. 第十九届泳联水中运动世锦赛
  11. 技术团队培养_如何在团队中培养伟大的文化
  12. 系统功能性/非功能性需求
  13. 从公司角度来看,为什么要招实习生?
  14. Python——dat文件批量合并为同一个csv文件
  15. CAD梦想画图中的“绘图工具——矩形”
  16. Tetramax生成SPF文件的方法
  17. 如何永久关闭windows安全中心?
  18. CentOS7编译WD My Cloud下的SVN(Subversion)(附编译好的SVN的链接)
  19. 灵性图书馆:好书推荐-《Datre书籍第一册》
  20. 杰里之解决开关机”POPO”声】【篇】

热门文章

  1. php未定义常量破解,PHP未定义的常量错误没有意义
  2. Python机器学习:评价分类结果004F1score
  3. r语言集合补集_R语言学习笔记(14)-常用包
  4. endnote怎么和word关联_把Endnote装进大脑:行走的文献管理者
  5. Android未发现目标设备,Android设备不会显示为Unity3d调试的目标
  6. html表单的首要标记是form,关于html中表单form标记的介绍
  7. java list排序工具类_java 之 Collections集合工具类排序
  8. python判断、创建文件夹
  9. pytorch 实现 LSTM AutoEncoder 与案例
  10. pandas dataframe根据筛选结果修改值