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字符串中的换行符和制表符介绍
May 03 Python
python实现NB-IoT模块远程控制
Jun 20 Python
解决Mac下首次安装pycharm无project interpreter的问题
Oct 29 Python
python实时获取外部程序输出结果的方法
Jan 12 Python
python pandas获取csv指定行 列的操作方法
Jul 12 Python
python yield关键词案例测试
Oct 15 Python
Python开发之基于模板匹配的信用卡数字识别功能
Jan 13 Python
Python可以实现栈的结构吗
May 27 Python
python字典的值可以修改吗
Jun 29 Python
Django model class Meta原理解析
Nov 14 Python
Python 列表反转显示的四种方法
Nov 16 Python
Python爬虫之用Xpath获取关键标签实现自动评论盖楼抽奖(二)
Jun 07 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新手上路(十二)
2006/10/09 PHP
php fsockopen中多线程问题的解决办法[翻译]
2011/11/09 PHP
PHP判断一个gif图片是否为动态图片的方法
2014/11/19 PHP
php mysql实现mysql_select_db选择数据库
2016/12/30 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
2018/02/23 PHP
laravel5.1框架基础之Blade模板继承简单使用方法分析
2019/09/05 PHP
JS中showModalDialog 的使用解析
2013/04/17 Javascript
JavaScript中数组成员的添加、删除介绍
2014/12/30 Javascript
jQuery实现鼠标经过图片变亮其他变暗效果
2015/05/08 Javascript
JavaScript字符集编码与解码详谈
2017/02/02 Javascript
JS实现的添加弹出层并完成锁屏操作示例
2017/04/07 Javascript
Nodejs 和 Electron ubuntu下快速安装过程
2018/05/04 NodeJs
d3.js实现自定义多y轴折线图的示例代码
2018/05/30 Javascript
详解express + mock让前后台并行开发
2018/06/06 Javascript
微信小程序框架wepy之动态控制类名
2018/09/14 Javascript
layui: layer.open加载窗体时出现遮罩层的解决方法
2019/09/26 Javascript
[45:34]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第一场 12.18
2020/12/19 DOTA
Python3实现生成随机密码的方法
2014/08/23 Python
Windows下用py2exe将Python程序打包成exe程序的教程
2015/04/08 Python
Python unittest 简单实现参数化的方法
2018/11/30 Python
python 为什么说eval要慎用
2019/03/26 Python
python打造爬虫代理池过程解析
2019/08/15 Python
python中利用matplotlib读取灰度图的例子
2019/12/07 Python
Python semaphore evevt生产者消费者模型原理解析
2020/03/18 Python
Python是怎样处理json模块的
2020/07/16 Python
python爬取股票最新数据并用excel绘制树状图的示例
2021/03/01 Python
利用SVG和CSS3来实现一个炫酷的边框动画
2015/07/22 HTML / CSS
Html5页面获取微信公众号的openid的方法
2020/05/12 HTML / CSS
幼儿园教研活动总结
2014/04/30 职场文书
中学生社区服务活动报告
2015/02/05 职场文书
中英文求职信范文
2015/03/19 职场文书
医药公司开票员岗位职责
2015/04/15 职场文书
运动会开幕式致辞
2015/07/29 职场文书
《小小的船》教学反思
2016/02/18 职场文书
2016年中学法制宣传日活动总结
2016/04/01 职场文书
试了下Golang实现try catch的方法
2021/07/01 Golang