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脚本将Bing的每日图片作为桌面的教程
May 04 Python
python如何实现远程控制电脑(结合微信)
Dec 21 Python
Python中列表、字典、元组数据结构的简单学习笔记
Mar 20 Python
python查看微信好友是否删除自己
Dec 19 Python
Python3一行代码实现图片文字识别的示例
Jan 15 Python
致Python初学者 Anaconda入门使用指南完整版
Apr 05 Python
Linux CentOS Python开发环境搭建教程
Nov 28 Python
解决PyCharm的Python.exe已经停止工作的问题
Nov 29 Python
详解Python安装tesserocr遇到的各种问题及解决办法
Mar 07 Python
python命名空间(namespace)简单介绍
Aug 10 Python
利用python实现.dcm格式图像转为.jpg格式
Jan 13 Python
python第三方库学习笔记
Feb 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
不用mod_rewrite直接用php实现伪静态化页面代码
2008/10/04 PHP
PHP导入Excel到MySQL的方法
2011/04/23 PHP
php中time()和mktime()方法的区别
2013/09/28 PHP
php中mt_rand()随机数函数用法
2014/11/24 PHP
PHP模板引擎Smarty自定义变量调解器用法
2016/04/11 PHP
PHP类相关知识点实例总结
2016/09/28 PHP
php 从一个数组中随机的取出若干个不同的数实例
2016/12/31 PHP
Javascript 实现TreeView CheckBox全选效果
2010/01/11 Javascript
仿jQuery的siblings效果的js代码
2011/08/09 Javascript
javascript获取和判断浏览器窗口、屏幕、网页的高度、宽度等
2014/05/08 Javascript
jQuery 过滤方法filter()选择具有特殊属性的元素
2014/06/15 Javascript
vue-resource 拦截器(interceptor)的使用详解
2017/07/04 Javascript
vue移动端裁剪图片结合插件Cropper的使用实例代码
2017/07/10 Javascript
js禁止浏览器页面后退功能的实例(推荐)
2017/09/01 Javascript
三分钟学会用ES7中的Async/Await进行异步编程
2018/06/14 Javascript
从组件封装看Vue的作用域插槽的实现
2019/02/12 Javascript
js/jquery遍历对象和数组的方法分析【forEach,map与each方法】
2019/02/27 jQuery
vue使用axios实现excel文件下载的功能
2020/07/16 Javascript
python不带重复的全排列代码
2013/08/13 Python
18个Python脚本可加速你的编码速度(提示和技巧)
2019/10/17 Python
python 遍历pd.Series的index和value
2019/11/26 Python
python sitk.show()与imageJ结合使用常见的问题
2020/04/20 Python
Python使用pyexecjs代码案例解析
2020/07/13 Python
Python求区间正整数内所有素数之和的方法实例
2020/10/13 Python
H5 meta小结(前端必看篇)
2016/08/24 HTML / CSS
我看到了用指针调用函数的不同语法形式
2014/07/16 面试题
求职自荐信范文格式
2013/11/29 职场文书
简历里的自我评价范文
2014/02/24 职场文书
天网工程实施方案
2014/03/26 职场文书
远程网络教育毕业生自我鉴定
2014/04/14 职场文书
优秀驾驶员先进事迹材料
2014/05/04 职场文书
水电站项目建议书
2014/05/12 职场文书
我们的节日国庆活动方案
2014/08/19 职场文书
家庭教育的心得体会
2014/09/01 职场文书
党委班子纠正“四风”问题整改措施
2014/10/28 职场文书
Python进度条的使用
2021/05/17 Python