Python中循环引用(import)失败的解决方法


Posted in Python onApril 22, 2018

前言

最近在开发智能家居项目hestia-rpi项目中,由于代码结构层级划分不合理,导致了循环引用(import)module失败的问题,错误如下:

Traceback (most recent call last):
  File "./main.py", line 8, in <module>
    from hestiarpi.library.server import server
  File "/home/pi/server/hestiarpi/library/server/server.py", line 4, in <module>
    from hestiarpi.library.brain import handler
  File "/home/pi/server/hestiarpi/library/brain/handler.py", line 5, in <module>
    from hestiarpi.library.brain import monitor
  File "/home/pi/server/hestiarpi/library/brain/monitor.py", line 6, in <module>
    from hestiarpi.library.server import server
ImportError: cannot import name server

原理

这个时候就有一个问题,当前脚本Main第一次执行,需要执行from A import ,发现没有A,就新建一个A在内存中,然后填充A模块的信息,就会去执行A,此时,A里面要 from Main import D,那么因为Main已被执行,就直接从内存的map中取得Main的信息,不过此时Main的信息还没有填充完,因为之前就是为了填充才转到A的,这时从已有的空的Main中拿不到D,就会报错,ImportError。

来自:https://3water.com/article/138673.htm

解决方案

方案一 合理划分项目代码层级

循环引用最大的本质问题是代码层级结构划分的不合理,所以最根本的、最合理的解决方案就是重新划分好代码的层级结构,使其合理化,自然就规避了循环引用的麻烦。

方案二 只引用当前的包,不引用具体的模块

如果你的代码是这样,那么这种方式是会奏效的。

修改前

# a.py
from B import b
def a():
 pass
# some codes
# b.py
from A import a
def b():
 a.a()
#some codes

修改后

# a.py
from B import b
def a():
 pass
# some codes
# b.py
import A
def b():
 A.a.a()
#some codes

方案二 将引用放到函数内部

如果你的代码是这样,那么这种方式是会奏效的。

修改前

# a.py
from B import b
def a():
 pass
# some codes
# b.py
from A import a
def b():
 a.a()
#some codes

修改后

# a.py
from B import b
def a():
 pass
# some codes
# b.py
def b():
 from A import a
 a.a()
#some codes

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
简单谈谈python中的多进程
Nov 06 Python
用Python shell简化开发
Aug 08 Python
一文带你了解Python中的字符串是什么
Nov 20 Python
python使用knn实现特征向量分类
Dec 26 Python
如何更优雅地写python代码
Jul 02 Python
python tqdm 实现滚动条不上下滚动代码(保持一行内滚动)
Feb 19 Python
Python面向对象魔法方法和单例模块代码实例
Mar 25 Python
利用Python如何实时检测自身内存占用
May 09 Python
opencv 图像加法与图像融合的实现代码
Jul 08 Python
告别网页搜索!教你用python实现一款属于自己的翻译词典软件
Jun 03 Python
Python list列表删除元素的4种方法
Nov 01 Python
Python Matplotlib绘制动画的代码详解
May 30 Python
Python 数据处理库 pandas进阶教程
Apr 21 #Python
PyQt5 QSerialPort子线程操作的实现
Apr 21 #Python
将python代码和注释分离的方法
Apr 21 #Python
Python基于百度AI的文字识别的示例
Apr 21 #Python
python实现随机调用一个浏览器打开网页
Apr 21 #Python
python爬虫 使用真实浏览器打开网页的两种方法总结
Apr 21 #Python
Python针对给定字符串求解所有子序列是否为回文序列的方法
Apr 21 #Python
You might like
使ecshop模板中可引用常量的实现方法
2011/06/02 PHP
仿Aspnetpager的一个PHP分页类代码 附源码下载
2012/10/08 PHP
php对包含html标签的字符串进行截取的函数分享
2014/06/19 PHP
php简单实现无限分类树形列表的方法
2015/03/27 PHP
php实现json编码的方法
2015/07/30 PHP
laravel5.0在linux下解决.htaccess无效和去除index.php的问题
2019/10/16 PHP
javascript 读取xml,写入xml 实现代码
2009/07/10 Javascript
JavaScript常用对象的方法和属性小结
2012/01/24 Javascript
javascript中有趣的反柯里化深入分析
2012/12/05 Javascript
js模拟select下拉菜单控件的代码
2013/05/08 Javascript
使用iframe window的scroll方法控制iframe页面滚动
2014/03/05 Javascript
js实现checkbox全选和反选示例
2014/05/01 Javascript
jQuery控制网页打印指定区域的方法
2015/04/07 Javascript
详解JavaScript的AngularJS框架中的作用域与数据绑定
2016/03/04 Javascript
浅析使用BootStrap TreeView插件实现灵活配置快递模板
2016/11/28 Javascript
JS实现的简易拖放效果示例
2016/12/29 Javascript
解决bootstrap下拉菜单点击立即隐藏bug的方法
2017/06/13 Javascript
vue 计时器组件的实现代码
2017/09/14 Javascript
加载 vue 远程代码的组件实例详解
2017/11/20 Javascript
javascript实现点击星星小游戏
2019/12/24 Javascript
jQuery实现开关灯效果
2020/08/02 jQuery
使用Python编写简单的画图板程序的示例教程
2015/12/08 Python
Python实现抢购IPhone手机
2018/02/07 Python
python 按不同维度求和,最值,均值的实例
2018/06/28 Python
解决Mac下首次安装pycharm无project interpreter的问题
2018/10/29 Python
使用python获取电脑的磁盘信息方法
2018/11/01 Python
解决.ui文件生成的.py文件运行不出现界面的方法
2019/06/19 Python
python中append实例用法总结
2019/07/30 Python
简单了解Python读取大文件代码实例
2019/12/18 Python
Python object类中的特殊方法代码讲解
2020/03/06 Python
python两种获取剪贴板内容的方法
2020/11/06 Python
医院护士见习期自我鉴定
2014/04/10 职场文书
微笑服务演讲稿
2014/05/13 职场文书
党的群众路线教育实践活动总结
2014/10/30 职场文书
开票证明
2015/06/23 职场文书
MySQL sql模式设置引起的问题
2022/05/15 MySQL