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使用xmlrpc实例讲解
Dec 17 Python
python集合用法实例分析
May 30 Python
python制作最美应用的爬虫
Oct 28 Python
利用numpy+matplotlib绘图的基本操作教程
May 03 Python
利用aardio给python编写图形界面
Aug 21 Python
linux安装python修改默认python版本方法
Mar 31 Python
Python面向对象程序设计多继承和多态用法示例
Apr 08 Python
Python爬虫实现“盗取”微信好友信息的方法分析
Sep 16 Python
基于matplotlib xticks用法详解
Apr 16 Python
Python中的全局变量如何理解
Jun 04 Python
Python依赖包迁移到断网环境操作
Jul 13 Python
Python+Tkinter制作专属图形化界面
Apr 01 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扩展模块memcached长连接使用方法分析
2014/12/24 PHP
php简单实现MVC
2015/02/05 PHP
php跨服务器访问方法小结
2015/05/12 PHP
php加密解密字符串示例
2016/10/13 PHP
php多进程并发编程防止出现僵尸进程的方法分析
2020/02/28 PHP
discuz论坛更换域名,详细文件修改步骤
2020/12/09 PHP
动态样式类封装JS代码
2009/09/02 Javascript
有效的捕获JavaScript焦点的方法小结
2009/10/08 Javascript
jQuery 常见学习网站与参考书
2009/11/09 Javascript
纯js网页画板(Graphics)类简介及实现代码
2012/12/24 Javascript
JS幻灯片可循环播放可平滑旋转带滚动导航(自写)
2013/08/05 Javascript
使用javascript做的一个随机点名程序
2014/02/13 Javascript
jQuery 仿百度输入标签插件附效果图
2014/07/04 Javascript
jQuery对val和atrr("value")赋值的区别介绍
2014/09/26 Javascript
jQuery设置单选按钮radio选中/不可用的实例代码
2016/06/24 Javascript
使用watch监听路由变化和watch监听对象的实例
2018/02/24 Javascript
echarts整合多个类似option的方法实例
2018/07/10 Javascript
微信小程序canvas.drawImage完全显示图片问题的解决
2018/11/30 Javascript
在layui.use 中自定义 function 的正确方法
2019/09/16 Javascript
[02:12]2015国际邀请赛 SHOWOPEN
2015/08/05 DOTA
python使用multiprocessing模块实现带回调函数的异步调用方法
2015/04/18 Python
详解Python程序与服务器连接的WSGI接口
2015/04/29 Python
Python实现堆排序的方法详解
2016/05/03 Python
Python编程之gui程序实现简单文件浏览器代码
2017/12/08 Python
python二进制文件的转译详解
2019/07/03 Python
浅谈django 重载str 方法
2020/05/19 Python
Tensorflow全局设置可见GPU编号操作
2020/06/30 Python
KIKO MILANO英国官网:意大利知名化妆品和护肤品品牌
2017/09/25 全球购物
JBL澳大利亚官方商店:扬声器、耳机和音响系统
2018/05/24 全球购物
美国购物网站:Clickhere2shop
2021/01/28 全球购物
应届生自荐书
2014/06/23 职场文书
小学生清明节演讲稿
2014/09/05 职场文书
网络销售员岗位职责
2015/04/11 职场文书
美容院管理规章制度
2015/08/05 职场文书
2016年寒假学习心得体会
2015/10/09 职场文书
python实现黄金分割法的示例代码
2021/04/28 Python