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字典排序实例详解
May 20 Python
Python提取网页中超链接的方法
Sep 18 Python
python数据类型_字符串常用操作(详解)
May 30 Python
Python语言描述机器学习之Logistic回归算法
Dec 21 Python
Django实现简单网页弹出警告代码
Nov 15 Python
pytorch中交叉熵损失(nn.CrossEntropyLoss())的计算过程详解
Jan 02 Python
pycharm下pyqt4安装及环境配置的教程
Apr 24 Python
Python常见反爬虫机制解决方案
Jun 01 Python
PyCharm 2020.2下配置Anaconda环境的方法步骤
Sep 23 Python
详解pycharm的python包opencv(cv2)无代码提示问题的解决
Jan 29 Python
Python实现我的世界小游戏源代码
Mar 02 Python
手残删除python之后的补救方法
Jun 26 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中file_exists()判断中文文件名无效的解决方法
2014/11/12 PHP
php实现按指定大小等比缩放生成上传图片缩略图的方法
2014/12/15 PHP
php实现Mysql简易操作类
2015/10/11 PHP
php的RSA加密解密算法原理与用法分析
2020/01/23 PHP
js活用事件触发对象动作
2008/08/10 Javascript
瀑布流布局并自动加载实现代码
2013/03/12 Javascript
js 本地预览的简单实现方法
2014/02/18 Javascript
用jquery写的菜单从左往右滑动出现
2014/04/11 Javascript
JavaScript实现使用Canvas绘制图形的基本教程
2016/10/27 Javascript
浅析location.href跨窗口调用函数
2016/11/22 Javascript
正则表达式基本语法及表单验证操作详解【基于JS】
2017/04/07 Javascript
vue component组件使用方法详解
2017/07/14 Javascript
javascript如何用递归写一个简单的树形结构示例
2017/09/06 Javascript
Vue的百度地图插件尝试使用
2017/09/06 Javascript
angular中ui calendar的一些使用心得(推荐)
2017/11/03 Javascript
详解nodeJs文件系统(fs)与流(stream)
2018/01/24 NodeJs
vue中如何使用ztree
2018/02/06 Javascript
vue实现的封装全局filter并统一管理操作示例
2020/02/02 Javascript
Pycharm编辑器技巧之自动导入模块详解
2017/07/18 Python
Python实现将一个正整数分解质因数的方法分析
2017/12/14 Python
python添加菜单图文讲解
2019/06/04 Python
给大家整理了19个pythonic的编程习惯(小结)
2019/09/25 Python
Python控制台输出时刷新当前行内容而不是输出新行的实现
2020/02/21 Python
详解django中Template语言
2020/02/22 Python
Python unittest装饰器实现原理及代码
2020/09/08 Python
Elasticsearch py客户端库安装及使用方法解析
2020/09/14 Python
python 发送get请求接口详解
2020/11/17 Python
非洲NO.1网上商店:Jumia肯尼亚
2016/08/18 全球购物
Street One瑞士:德国现代时装公司
2019/10/09 全球购物
2014年高三毕业生自我评价
2014/01/11 职场文书
施工协议书范本
2014/04/22 职场文书
公司募捐倡议书
2014/05/14 职场文书
银行职员工作失误检讨书
2014/10/14 职场文书
创业计划书之面包店
2019/09/12 职场文书
nginx常用命令放入shell脚本详解
2021/03/31 Servers
Nginx+SpringBoot实现负载均衡的示例
2021/03/31 Servers