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自动调用IE打开某个网站的方法
Jun 03 Python
通过实例浅析Python对比C语言的编程思想差异
Aug 30 Python
使用Python & Flask 实现RESTful Web API的实例
Sep 19 Python
python 借助numpy保存数据为csv格式的实现方法
Jul 04 Python
安装好Pycharm后如何配置Python解释器简易教程
Jun 28 Python
Django REST framework 单元测试实例解析
Nov 07 Python
python数据化运营的重要意义
Nov 25 Python
基于python判断目录或者文件代码实例
Nov 29 Python
python实现横向拼接图片
Mar 23 Python
在django admin中配置搜索域是一个外键时的处理方法
May 20 Python
python中如何写类
Jun 29 Python
Python字节单位转换(将字节转换为K M G T)
Mar 02 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 解析xml 的四种方法详细介绍
2016/10/26 PHP
php实用代码片段整理
2016/11/12 PHP
PHP命名空间namespace及use的简单用法分析
2018/08/03 PHP
php+mysql+ajax 局部刷新点赞/取消点赞功能(每个账号只点赞一次)
2020/07/24 PHP
一个符号插入器 中用到的js代码
2007/09/04 Javascript
angularjs中的单元测试实例
2014/12/06 Javascript
jQuery实现类似老虎机滚动抽奖效果
2015/08/06 Javascript
再谈javascript常见错误及解决方法
2016/09/16 Javascript
jQuery实现页面顶部下拉广告
2016/12/30 Javascript
jQuery菜单实例(全选,反选,取消)
2017/08/28 jQuery
基于Datatables跳转到指定页的简单实例
2017/11/09 Javascript
jQuery+Cookie实现切换皮肤功能【附源码下载】
2018/03/25 jQuery
vue实现div拖拽互换位置
2020/07/29 Javascript
解决layui checkbox 提交多个值的问题
2019/09/02 Javascript
Vue 刷新当前路由的实现代码
2019/09/26 Javascript
bootstrapValidator表单校验、更改状态、新增、移除校验字段的实例代码
2020/05/19 Javascript
[03:35]2018年度DOTA2最佳辅助位选手5号位-完美盛典
2018/12/17 DOTA
Python比较两个图片相似度的方法
2015/03/13 Python
详解Python中的各种函数的使用
2015/05/24 Python
对Python3.6 IDLE常用快捷键介绍
2018/07/16 Python
python实现AES加密和解密
2019/03/27 Python
python的turtle库使用详解
2019/05/10 Python
python中while和for的区别总结
2019/06/28 Python
Python Web框架之Django框架cookie和session用法分析
2019/08/16 Python
浅谈python print(xx, flush = True) 全网最清晰的解释
2020/02/21 Python
Python爬虫回测股票的实例讲解
2021/01/22 Python
美国知名生活购物网站:Goop
2017/11/03 全球购物
Koral官方网站:女性时尚运动服
2019/04/10 全球购物
Ejb技术面试题
2015/04/29 面试题
基于Python 函数和方法的区别说明
2021/03/24 Python
财产公证书
2014/04/10 职场文书
物理教育专业求职信
2014/06/25 职场文书
安全责任书范文
2014/08/25 职场文书
中秋晚会致辞
2015/07/31 职场文书
用python自动生成日历
2021/04/24 Python
解析python中的jsonpath 提取器
2022/01/18 Python