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 元类使用说明
Dec 18 Python
python去除空格和换行符的实现方法(推荐)
Jan 04 Python
Python使用matplotlib的pie函数绘制饼状图功能示例
Jan 08 Python
selenium + python 获取table数据的示例讲解
Oct 13 Python
numpy 计算两个数组重复程度的方法
Nov 07 Python
利用Python正则表达式过滤敏感词的方法
Jan 21 Python
python3实现点餐系统
Jan 24 Python
Python 使用 attrs 和 cattrs 实现面向对象编程的实践
Jun 12 Python
pytorch中nn.Conv1d的用法详解
Dec 31 Python
使用Python对Dicom文件进行读取与写入的实现
Apr 20 Python
TensorFlow tf.nn.conv2d_transpose是怎样实现反卷积的
Apr 20 Python
pytorch实现查看当前学习率
Jun 24 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
MYSQL数据库初学者使用指南
2006/11/16 PHP
php获取参数的几种方法总结
2014/02/18 PHP
php连接odbc数据源并保存与查询数据的方法
2014/12/24 PHP
php实现只保留mysql中最新1000条记录
2015/06/18 PHP
PHP正则获取页面所有图片地址
2016/03/23 PHP
javascript AutoScroller 函数类
2009/05/29 Javascript
11款基于Javascript的文件管理器
2009/10/25 Javascript
Jquery iframe内部出滚动条
2010/02/11 Javascript
判断控件是否已加载完成的代码
2010/02/24 Javascript
bgsound 背景音乐 的一些常用方法及特殊用法小结
2010/05/11 Javascript
javascript实现图片切换的幻灯片效果源代码
2012/12/12 Javascript
关于extjs treepanel复选框选中父节点与子节点的问题
2013/04/02 Javascript
jQuery动态添加、删除元素的方法
2014/01/09 Javascript
jQuery轻松实现表格的隔行变色和点击行变色的实例代码
2016/05/09 Javascript
微信小程序 向左滑动删除功能的实现
2017/03/10 Javascript
JQuery和html+css实现带小圆点和左右按钮的轮播图实例
2017/07/22 jQuery
浅谈angular2路由预加载策略
2017/10/04 Javascript
nodejs实现的简单web服务器功能示例
2018/03/15 NodeJs
微信小程序如何获取用户收货地址
2018/11/27 Javascript
Vue 之孙组件向爷组件通信的实现
2019/04/23 Javascript
el-input 标签中密码的显示和隐藏功能的实例代码
2019/07/19 Javascript
使用python调用zxing库生成二维码图片详解
2017/01/10 Python
PyQt5每天必学之带有标签的复选框
2018/04/19 Python
python实现批量解析邮件并下载附件
2018/06/19 Python
Python中的Numpy矩阵操作
2018/08/12 Python
详解pyenv下使用python matplotlib模块的问题解决
2018/11/29 Python
Django组件之cookie与session的使用方法
2019/01/10 Python
django和vue实现数据交互的方法
2019/08/21 Python
Python计算机视觉里的IOU计算实例
2020/01/17 Python
英国和世界各地预订便宜的酒店:LateRooms.com
2019/05/05 全球购物
租赁意向书范本
2014/04/01 职场文书
县政府班子个人对照检查材料
2014/10/05 职场文书
2015年平安创建工作总结
2015/04/29 职场文书
电影雨中的树观后感
2015/06/15 职场文书
党员廉政准则心得体会
2016/01/20 职场文书
CentOS7设置ssh服务以及端口修改方式
2022/12/24 Servers