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之永远强大的函数
Sep 14 Python
在Mac OS上搭建Python的开发环境
Dec 24 Python
Python列表list解析操作示例【整数操作、字符操作、矩阵操作】
Jul 25 Python
Python+OpenCV人脸检测原理及示例详解
Oct 19 Python
python3中的md5加密实例
May 29 Python
浅谈python脚本设置运行参数的方法
Dec 03 Python
python顺序执行多个py文件的方法
Jun 29 Python
Python使用指定字符长度切分数据示例
Dec 05 Python
pandas的相关系数与协方差实例
Dec 27 Python
Python startswith()和endswith() 方法原理解析
Apr 28 Python
Python使用re模块验证危险字符
May 21 Python
Python matplotlib多个子图绘制整合
Apr 13 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
一个好用的PHP验证码类实例分享
2013/12/27 PHP
PHP基于GD库的缩略图生成代码(支持jpg,gif,png格式)
2014/06/19 PHP
php导出CSV抽象类实例
2014/09/24 PHP
php版微信返回用户text输入的方法
2016/11/14 PHP
javascript 单选框,多选框美化代码
2008/08/01 Javascript
jquery连缀语法如何实现
2012/11/29 Javascript
IE8对JS通过属性和数组遍历解析不一样的地方探讨
2013/05/06 Javascript
JS Array.slice 截取数组的实现方法
2016/01/02 Javascript
jQuery unbind()方法实例详解
2016/01/19 Javascript
JS与jQuery实现隔行变色的方法
2016/09/09 Javascript
angularJS Provider、factory、service详解及实例代码
2016/09/21 Javascript
快速解决vue动态绑定多个class的官方实例语法无效的问题
2018/09/05 Javascript
angular2 组件之间通过service互相传递的实例
2018/09/30 Javascript
其实你可以少写点if else与switch(推荐)
2019/01/10 Javascript
详解Vue-cli3 项目在安卓低版本系统和IE上白屏问题解决
2019/04/14 Javascript
layui 数据表格 根据值(1=业务,2=机构)显示中文名称示例
2019/10/26 Javascript
JavaScript canvas实现雪花随机动态飘落
2020/02/08 Javascript
JavaScript 中判断变量是否为数字的示例代码
2020/10/22 Javascript
ant design vue中日期选择框混合时间选择器的用法说明
2020/10/27 Javascript
Vue项目打包部署到apache服务器的方法步骤
2021/02/01 Vue.js
[02:57]2014DOTA2国际邀请赛-观众采访
2014/07/19 DOTA
[01:11:28]DOTA2-DPC中国联赛定级赛 RNG vs Phoenix BO3第一场 1月8日
2021/03/11 DOTA
Python队列的定义与使用方法示例
2017/06/24 Python
Python Json序列化与反序列化的示例
2018/01/31 Python
python之pandas用法大全
2018/03/13 Python
解决Python命令行下退格,删除,方向键乱码(亲测有效)
2020/01/16 Python
Django实现后台上传并显示图片功能
2020/05/29 Python
python正则表达式 匹配反斜杠的操作方法
2020/08/07 Python
利用pipenv和pyenv管理多个相互独立的Python虚拟开发环境
2020/11/01 Python
python模块内置属性概念及实例
2021/02/18 Python
KENZO官网:高田贤三在法国创立的品牌
2019/05/16 全球购物
Wedgwood英国官方网站:英式精致骨瓷餐具、礼品与生活精品,源于1759年
2019/09/02 全球购物
教师自查自纠材料
2014/10/14 职场文书
2014年综合治理工作总结
2014/11/20 职场文书
专业技术人员年度考核评语
2014/12/31 职场文书
2015年企业员工工作总结范文
2015/05/21 职场文书