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 相关文章推荐
400多行Python代码实现了一个FTP服务器
May 10 Python
Python在Console下显示文本进度条的方法
Feb 14 Python
Python科学计算之Pandas详解
Jan 15 Python
Python模拟简单电梯调度算法示例
Aug 20 Python
Python multiprocessing多进程原理与应用示例
Feb 28 Python
Python操作rabbitMQ的示例代码
Mar 19 Python
使用Python控制摄像头拍照并发邮件
Apr 23 Python
python web框架中实现原生分页
Sep 08 Python
Python使用matplotlib绘制Logistic曲线操作示例
Nov 28 Python
Pandas-Cookbook 时间戳处理方式
Dec 07 Python
在TensorFlow中屏蔽warning的方式
Feb 04 Python
使用Python绘制台风轨迹图的示例代码
Sep 21 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
Zend studio for eclipse中使php可以调用mysql相关函数的设置方法
2008/10/13 PHP
使用php判断网页是否gzip压缩
2013/06/25 PHP
WordPress中的shortcode短代码功能使用详解
2016/05/17 PHP
javascript 操作文件 实现方法小结
2009/07/02 Javascript
Tab页界面 用jQuery及Ajax技术实现(php后台)
2011/10/12 Javascript
Jquery:ajax实现翻页无刷新功能代码
2013/08/05 Javascript
JavaScript学习笔记之Function对象
2015/01/22 Javascript
JS实现控制表格行文本对齐的方法
2015/03/30 Javascript
微信小程序开发之录音机 音频播放 动画实例 (真机可用)
2016/12/08 Javascript
jquery实时获取时间的简单实例
2017/01/26 Javascript
JS实现基于Sketch.js模拟成群游动的蝌蚪运动动画效果【附demo源码下载】
2017/08/18 Javascript
浅谈在vue中使用mint-ui swipe遇到的问题
2018/09/27 Javascript
JavaScript寄生组合式继承原理与用法分析
2019/01/11 Javascript
五句话帮你轻松搞定js原型链
2020/12/09 Javascript
[02:56]DOTA2矮人直升机 英雄基础教程
2013/11/26 DOTA
[01:10]DOTA2英雄背景故事第四期之混沌法则混沌骑士
2020/07/16 DOTA
python多线程http下载实现示例
2013/12/30 Python
python中嵌套函数的实操步骤
2019/02/27 Python
由Python编写的MySQL管理工具代码实例
2019/04/09 Python
Django数据库类库MySQLdb使用详解
2019/04/28 Python
opencv实现简单人脸识别
2021/02/19 Python
python使用pip安装SciPy、SymPy、matplotlib教程
2019/11/20 Python
tensorflow如何继续训练之前保存的模型实例
2020/01/21 Python
CSS3的常见transformation图形变化用法小结
2016/05/13 HTML / CSS
探索欧洲最好的品牌:Bombinate
2019/06/14 全球购物
香港演唱会订票网站:StubHub香港
2019/10/10 全球购物
Currentbody德国站:健康与美容技术专家
2020/04/05 全球购物
.NET面试问题集
2015/12/08 面试题
护理专业毕业生自我鉴定
2013/10/08 职场文书
校园餐饮创业计划书
2014/01/10 职场文书
自我鉴定书
2014/03/24 职场文书
2014年文学毕业生自我鉴定
2014/04/23 职场文书
正风肃纪剖析材料范文
2014/10/10 职场文书
三好学生事迹材料
2014/12/24 职场文书
Python列表删除重复元素与图像相似度判断及删除实例代码
2021/05/07 Python
前端JS获取URL参数的4种方法总结
2022/04/05 Javascript