Python中循环引用(import)失败的解决方法

  原文链接:http://blog.ihuxu.com/the-solution-to-the-problem-of-circular-import-in-python/

  我是采用方案三 "将引用放到函数内部"解决了这个问题。下面为原文。

  前言

  最近在开发智能家居项目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。

  解决方案

  方案一 合理划分项目代码层级

  循环引用最大的本质问题是代码层级结构划分的不合理,所以最根本的、最合理的解决方案就是重新划分好代码的层级结构,使其合理化,自然就规避了循环引用的麻烦。

  方案二 只引用当前的包,不引用具体的模块

  如果你的代码是这样,那么这种方式是会奏效的。

  修改前

# 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

原文地址:https://www.cnblogs.com/lnlvinso/p/9757763.html

时间: 2024-08-15 03:19:28

Python中循环引用(import)失败的解决方法的相关文章

python中循环引用导致内存泄漏小案例

首先定义一个Person类和一个Dog类,然后分别实例化对象p和d,给p对象添加一个pet属性 给d对象添加一个master属性此时Person和Dog的应用计数都为2,当del p 和del d后Person 和Dog的应用计数都为1,就造成了循环引用导致内存不能释放 最终导致内存泄漏. 以下图片是没有循环应用的代码执行结果 以下图片是循环引用后代码执行结果 原文地址:https://www.cnblogs.com/chen55555/p/11079223.html

python中常见的那些错误及解决方法(不定更新)

错误1:SyntaxError: 'return' outside function解决:将return放在方法体中return不能在方法以外使用 错误2:TypeError: must be str, not int类型错误 必须是一个字符串 不能是数字解决办法:使用+拼接的时候 必须使用字符串,或者将数字转化成字符串 错误3:SyntaxError: invalid syntax语法错误 非法的语法解决办法:看报错信息在第几行 ,从这一行往上找错误 错误4:IndentationError:

Android React Native在Android Studio中执行bundleReleaseJsAndAssets 打包失败的解决方法

这个坑在文章记一次在Windows上搭建React Native Android环境踩过的坑中我已经提到过,当时找不到解决方法,只能开一个命令提示符终端独立执行打包.就像这样子 react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output C:\Users\Administrator\Desktop\AwesomeProject\android\app\build\

python中,round 五舍的解决方法

先看一个图: 可以发现0.5被完美舍去,并没有达到我们想要的  四舍五入效果 原因: 2.55 保留一位小数,最后结果应该为2.6. 但实际上 2.55被放大后,变成了2.54999.2.549保留一位小数 自然等于2.5 上面的0.5也是同一个道理 解决方法: 例如 0.5 进1    就+0.01; 0.05进1  就+ 0.001  以此类推 原文地址:https://www.cnblogs.com/zhangyue233/p/10709730.html

在win8/win8.1中wamp启动curl失败的解决方法

因为最近准备好好学习一下cURL,所以在我的win8.1本本上安装了一个wamp,安装完毕之后一切正常,准备操练一下cURL的时候,出现报错,说是没有定义curl_init();这个函数.用phpinfo()看了一下配置,果然没有发现加载cURL.检查了php.ini文件,配置确实没有错误,然后就在网上进行了搜索,发现还真是有不少同样的情况,他们说的解决办法也很多,什么修改这个配置那个配置了,把三个***.dll文件复制到system32文件夹下了,但是我的直觉是就是php_curl.dll文件

VM虚拟机中Ubuntu中执行apt-get update失败的解决方法(可能有效)

首先确保虚拟机是连接网络的,可以用ping命令检测一下看是否连通网络.采用nat网络的时候确保服务是开的. 如果之前执行过apt-get update命令但是失败了,执行一下      rm -rf /var/lib/apt/lists/partial/*     和  sudo apt-get clean 命令,之后更换源,网上有很多可以试一下,这里推荐一下这个网址      https://launchpad.net/ubuntu/+archivemirrors,用gedit /etc/ap

Python语言中循环引用(import)失败的解决方案

最近在开发智能家居项目hestia-rpi项目中,由于代码结构层级划分不合理,导致了循环引用(import)module失败的问题,错误如下: 1 2 3 4 5 6 7 8 9 10 Traceback (most recent call last):   File "./main.py", line 8, in <module>     from hestiarpi.library.server import server   File

python中的引用

作为一个python初学者,今天被一个python列表和词典引用的问题折磨了很久,但其实了解了缘由也很简单,记录在此备忘. 首先背书python中的引用对象问题: 1. python不允许程序员选择采用传值还是传引用.Python参数传递采用的肯定是“传对象引用”的方式.实际上,这种方式相当于传值和传引用的一种综合.如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于通过“传引用”来传递对象.如果函数收到的是一个不可变对象(比如数字.字符或者元组)的引用,就不能

python中from module import * 的一个陷阱

from module import *把module中的成员全部导到了当前的global namespace,访问起来就比较方便了.当然,python style一般不建议这么做,因为可能引起name conflict. 但还有另外一个问题 - 你以为你修改了某个变量,其实,被from module import *后的那个并没有被更新,非常危险,因为程序有可能还可以正常运行, 只不过结果错了,到了production才被发现就比较惨了. 举个例子: 你定义了一些变量在base模块中: # r