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 03 Python
浅谈python中的实例方法、类方法和静态方法
Feb 17 Python
ubuntu中配置pyqt4环境教程
Dec 27 Python
django-rest-framework解析请求参数过程详解
Jul 18 Python
pandas DataFrame创建方法的方式
Aug 02 Python
10分钟教你用python动画演示深度优先算法搜寻逃出迷宫的路径
Aug 12 Python
详解一种用django_cache实现分布式锁的方式
Sep 01 Python
Django中提示消息messages的设置方式
Nov 15 Python
Django 创建后台,配置sqlite3教程
Nov 18 Python
Python中文分词库jieba,pkusegwg性能准确度比较
Feb 11 Python
Python实现UDP程序通信过程图解
May 15 Python
如何在pycharm中安装第三方包
Oct 27 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
攻克CakePHP系列一 连接MySQL数据库
2008/10/22 PHP
PHP最常用的ini函数分析 针对PHP.ini配置文件
2010/04/22 PHP
PHP使用递归方式列出当前目录下所有文件的方法
2015/06/02 PHP
php+jQuery实现的三级导航栏下拉菜单显示效果
2017/08/10 PHP
php使用gearman进行任务分发操作实例详解
2020/02/26 PHP
基于jquery的跟随屏幕滚动代码
2012/07/24 Javascript
js异常捕获方法介绍
2013/04/10 Javascript
你必须知道的Javascript知识点之"this指针"的应用
2013/04/23 Javascript
Jquery each方法跳出循环,并获取返回值(实例讲解)
2013/12/12 Javascript
Bootstrap Metronic完全响应式管理模板学习笔记
2016/07/08 Javascript
JS在Chrome浏览器中showModalDialog函数返回值为undefined的解决方法
2016/08/03 Javascript
JS制作图形验证码实现代码
2020/10/19 Javascript
对javascript继承的理解
2016/10/11 Javascript
js获取浏览器高度 窗口高度 元素尺寸 偏移属性的方法
2016/11/21 Javascript
利用vue实现模态框组件
2016/12/19 Javascript
vue toggle做一个点击切换class(实例讲解)
2018/03/13 Javascript
JS实现HTML页面中动态显示当前时间完整示例
2018/07/30 Javascript
vue中的循环对象属性和属性值用法
2020/09/04 Javascript
解决removeEventListener 无法清除监听的问题
2020/10/30 Javascript
JS canvas实现画板和签字板功能
2021/02/23 Javascript
[03:59]DOTA2英雄梦之声_第07期_水晶室女
2014/06/23 DOTA
python实现目录树生成示例
2014/03/28 Python
Python和Ruby中each循环引用变量问题(一个隐秘BUG?)
2014/06/04 Python
Python中的rfind()方法使用详解
2015/05/19 Python
Python获取文件所在目录和文件名的方法
2017/01/12 Python
python正则实现计算器功能
2017/12/14 Python
python框架中flask知识点总结
2018/08/17 Python
python实现二维数组的对角线遍历
2019/03/02 Python
Python批量查询关键词微信指数实例方法
2019/06/27 Python
window7下的python2.7版本和python3.5版本的opencv-python安装过程
2019/10/24 Python
利用CSS3制作简单的3d半透明立方体图片展示
2017/03/25 HTML / CSS
英国奢侈品概念店:Base Blu
2019/05/16 全球购物
工商管理系学生的自我评价分享
2013/11/29 职场文书
单位办理社保介绍信
2014/01/10 职场文书
初中作文评语集锦
2014/12/25 职场文书
2019奶茶店创业计划书范本!
2019/07/15 职场文书