【记录】Python3|Python出现循环引用模块怎么办?(又称循环依赖)
前言
在Python开发过程中,尤其是在大型项目中,我们经常会遇到模块间相互依赖的情况。这种相互依赖,即所谓的“循环引用”,往往会导致代码难以维护,并可能引发各种运行时问题。在这篇博客中,我们将探讨Python中循环引用的问题,并提供一些有效的解决方案。
问题
循环引用通常发生在两个或多个模块互相导入对方的情况下。例如,模块A导入模块B,同时模块B也导入模块A。这种情况下,如果不妥善处理,可能会导致程序在运行时遇到导入错误或者初始化失败的问题。
解决办法
局部导入:
最简单且常用的方法是将导入语句放在函数或方法内部。这种做法可以延迟导入的过程,直到函数被调用时才进行,从而避免初始化时的循环依赖。说实在话,我是真没想到解决办法竟然如此简单!!!请让我们谢谢ChatGPT!
# 在module1.py
def func1():
from module2 import func2
# 使用 func2 # 在module2.py
def func2():
from module1 import func1
# 使用 func1
重构代码结构:
通过重新组织代码,将相互依赖的部分放入同一个模块中,或者创建一个新的模块来存放共享的代码部分。延迟类型注解(Python 3.7+):
对于类型注解中的循环依赖,使用from __future__ import annotations可以延迟类型注解的评估。使用接口或抽象类:
定义接口或抽象基类,并在一个模块中实现这些接口,而在另一个模块中引用,可以减少直接的模块依赖。依赖注入:
将需要的对象或函数作为参数传递给函数或类,而非直接在模块层面导入。
结束语
循环引用是Python项目中常见的一个问题,但通过上述方法,我们可以有效地解决或绕过这一难题。值得注意的是,虽然局部导入是一个快速解决问题的办法,但从长远来看,重构代码以消除循环依赖通常是更健康和可持续的解决方案。希望这篇博客能帮助你在Python项目中更好地处理模块间的依赖关系!
ps: 我最初采用了局部导入的方式,但是发现还是有解决不了的问题(比如局部导入后该导入又被其他文件在其他地方引用,总之就是极其复杂)。最后小小地重新整理了一下代码。我的做法是这样的:
- 对于多个文件需要共享的内容,使用全局变量globs.py。
- 然后将处理全局变量的函数抽出来作为一个文件utils.py。
- 其他文件调用utils.py文件,而utils.py只调用全局变量globs.py。这样就不会出现循环依赖的问题。
本账号所有文章均为原创,欢迎转载,请注明文章出处:https://blog.csdn.net/qq_46106285/article/details/135348198。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。
【记录】Python3|Python出现循环引用模块怎么办?(又称循环依赖)的更多相关文章
- 第二十一天python3 python的正则表达式re模块学习
python的正则表达式 python使用re模块提供了正则表达式处理的能力: 常量 re.M re.MULTILINE 多行模式 re.S re.DOTALL 单行模式 re.I re.IGNORE ...
- 2211-22学习记录之python百分数,time模块
百分数 print(' {:.0%}'.format(84/100)) 输出为84% 以上百分数输出是使用到了字符串格式化函数format(),在其中将分数42/50作为值给传递了进去.如果将分子分母 ...
- 使用gc、objgraph干掉python内存泄露与循环引用!
Python使用引用计数和垃圾回收来做内存管理,前面也写过一遍文章<Python内存优化>,介绍了在python中,如何profile内存使用情况,并做出相应的优化.本文介绍两个更致命的问 ...
- Python对象的循环引用问题
目录 Python对象循环引用 循环引用垃圾回收算法 容器对象 生成容器对象 追踪容器对象 结束追踪容器对象 分代容器对象链表 何时执行循环引用垃圾回收 循环引用的垃圾回收 循环引用中的终结器 pyt ...
- Spring 循环引用(二)源码分析
Spring 循环引用(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring 循环引用相关文章: & ...
- ios - block循环引用Demo示例
当实例变量中有了block属性,并且用copy来修饰,但是当调用block中的代码的时候,如果block中运用了self.属性的时候回造成循环引用. // // ViewController.h // ...
- block使用小结、在arc中使用block、如何防止循环引用
引言 使用block已经有一段时间了,感觉自己了解的还行,但是几天前看到CocoaChina上一个关于block的小测试主题: [小测试]你真的知道blocks在Objective-C中是怎么工作的吗 ...
- Atitit.json xml 序列化循环引用解决方案json
Atitit.json xml 序列化循环引用解决方案json 1. 循环引用1 2. 序列化循环引用解决方法1 2.1. 自定义序列化器1 2.2. 排除策略1 2.3. 设置序列化层次,一般3级别 ...
- Samples DataBind FastJson循环引用问题
Fastjson full support databind, it's simple to use. Encode import com.alibaba.fastjson.JSON; Group g ...
- 小结OC中Retain cycle(循环引用)
retain cycle 的产生 说到retain cycle,首先要提一下Objective-C的内存管理机制. 作为C语言的超集,Objective-C延续了C语言中手动管理内存的方式,但是区别于 ...
随机推荐
- RabbitMQ(十)——消息优先级
RabbitMQ系列 RabbitMQ(一)--简介 RabbitMQ(二)--模式类型 RabbitMQ(三)--简单模式 RabbitMQ(四)--工作队列模式 RabbitMQ(五)--发布订阅 ...
- 攻城攻心的混淆大师——深入解析第十八届CISCN x 第二届长城杯初赛Reverse赛题vt
前言 在初赛结束近两月之际,笔者在复盘过程中意外发现了这道当时无人能解的难题.经过两日深入的探索与钻研,笔者终于成功地对这道赛题进行了全面的解构.在品味破译flag所带来的喜悦之余,笔者亦深感此题蕴含 ...
- [SDOI2015] 序列统计 题解
乘法并不容易用 FFT 或 NTT 维护,考虑在模意义下化乘为加. 化乘为加主要有两种方法:\(\log\) 和 \(\gamma\)(指标),由于在取模意义下,所以使用后者. 那剩下的部分就是快速幂 ...
- 【COM3D2Mod 制作教程(8)】实战!制作衣服部分(下)
[COM3D2Mod 制作教程(8)]实战!制作衣服部分(下) 制作袜子 Mod 体会了裙子 Mod 的制作流程,不知道你有没有被麻烦的权重和形态键搞崩溃过,现在做袜子难道还得在来一遍?而且裆下的权重 ...
- Zookeeper - 客户端常用命令
查看客户端命令帮助信息 查看Zookeeper的版本 查看使用过的历史命令 查看根目录下的znode 创建znode 查看节点信息 修改znode的内容 删除znode 关闭连接 连接客户端 退出客户 ...
- Flink学习(三) 批流版本的wordcount Scala版本
批处理代码: package com.wyh.wc import org.apache.flink.api.scala._ /** * 批处理代码 */ object WordCount { def ...
- P4118 [Ynoi2018] 末日时在做什么?有没有空?可以来拯救吗?
YNOI 智慧题 EasyVer1 [Ynoi Easy Round 2015] 世上最幸福的女孩 EasyVer2 小白逛公园 先看 EasyVer2 单点修改 区间查询最大子段和 考虑在线段树维护 ...
- PowerShell开发小工具 · 四张照片拼成一张
小工具的设计与实现------选四张照片拼成一张照片. 很经典的应用情景,市面上有很多类似的小软件,特别是手机应用.为了方便学习巩固PowerShell,今天笔者使用它来实现. [设计思路] 选择四张 ...
- sql server 2017 STRING_AGG() 替代方案
SELECT @StuId='"'+STRING_AGG(Id,'","')+'"'FROM( SELECT 'a'+cast(Id as varchar) I ...
- linux下nginx常用命令
1.查找nginx路径:whereis nginx2.启动 service nginx start3.查看Nginx的版本号:nginx -V4.停止 nginx -s stop5.退出 nginx ...