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打开文件并获取文件相关属性的方法
Apr 23 Python
python通过索引遍历列表的方法
May 04 Python
深入浅析Python字符编码
Nov 12 Python
python实现守护进程、守护线程、守护非守护并行
May 05 Python
完美解决在oj中Python的循环输入问题
Jun 25 Python
Django Rest framework之权限的实现示例
Dec 17 Python
Django项目中添加ldap登陆认证功能的实现
Apr 04 Python
python flask框架实现传数据到js的方法分析
Jun 11 Python
Python实现栈的方法详解【基于数组和单链表两种方法】
Feb 22 Python
简单了解python shutil模块原理及使用方法
Apr 28 Python
Python爬虫实例——scrapy框架爬取拉勾网招聘信息
Jul 14 Python
Python+腾讯云服务器实现每日自动健康打卡
Dec 06 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
使用Appcan客户端自动更新PHP版本号(全)
2015/07/31 PHP
bgsound 背景音乐 的一些常用方法及特殊用法小结
2010/05/11 Javascript
jQuery对象数据缓存Cache原理及jQuery.data方法区别介绍
2013/04/07 Javascript
JQuery AJAX 中文乱码问题解决
2013/06/05 Javascript
jquery修改网页背景颜色通过css方法实现
2014/06/06 Javascript
我的Node.js学习之路(二)NPM模块管理
2014/07/06 Javascript
JS+CSS3模拟溢出滚动效果
2016/08/12 Javascript
jquery获取点击控件的绝对位置简单实例
2016/10/13 Javascript
利用jquery实现验证输入的是否是数字、小数,包含保留几位小数
2016/12/07 Javascript
jQuery实现加入收藏夹功能(主流浏览器兼职)
2016/12/24 Javascript
简单的vue-resourse获取json并应用到模板示例
2017/02/10 Javascript
详解nodejs中的process进程
2017/03/19 NodeJs
angular6.x中ngTemplateOutlet指令的使用示例
2018/08/09 Javascript
在Vue 中使用Typescript的示例代码
2018/09/10 Javascript
vue数据初始化initState的实例详解
2019/04/11 Javascript
微信小程序如何修改radio和checkbox的默认样式和图标
2019/07/24 Javascript
Bootstrap table 服务器端分页功能实现方法示例
2020/06/01 Javascript
微信小程序选择图片控件
2021/01/19 Javascript
Python双精度浮点数运算并分行显示操作示例
2017/07/21 Python
Python实现的爬虫刷回复功能示例
2018/06/07 Python
详解python中的线程与线程池
2019/05/10 Python
Python OrderedDict字典排序方法详解
2020/05/21 Python
python字典与json转换的方法总结
2020/12/28 Python
HTML5 标准将把互联网视频扔回到黑暗时代
2010/02/10 HTML / CSS
Waterford加拿大官方网站:世界著名的水晶杯品牌
2016/11/01 全球购物
为有想象力的人提供的生活方式商店:Firebox
2018/06/04 全球购物
Parfume Klik丹麦:香水网上商店
2018/07/10 全球购物
招商业务员岗位职责
2013/12/16 职场文书
婚礼主持词开场白
2014/03/13 职场文书
条幅标语大全
2014/06/20 职场文书
英语课外活动总结
2014/08/27 职场文书
三严三实民主生活会发言稿
2014/10/13 职场文书
2015年党风廉政承诺书
2015/01/22 职场文书
Nginx stream 配置代理(Nginx TCP/UDP 负载均衡)
2021/11/17 Servers
Python内置包对JSON文件数据进行编码和解码
2022/04/12 Python
Springboot集成kafka高级应用实战分享
2022/08/14 Java/Android