【记录】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语言中手动管理内存的方式,但是区别于 ...
随机推荐
- MYSQL数据空洞解析
## 背景引入 MYSQL中数据表A,在删除了一半的数据后,发现表空间的大小并没有减少,这是什么原因导致的呢? 定义 当对一定量数据执行delete操作时,MySQL将数据删除后进而导致页合并或者页删 ...
- DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
你好呀,我是歪歪. 五年前,2020 年,我写文章的时候曾经遇到过一个技术问题,百思不得其解,当时把那个问题归类为玄学问题. 后来也会偶尔想起这个问题,但是我早就不纠结于这个问题了,没再去研究过. 前 ...
- 正则表达式匹配邮箱,IP地址,URL
参考链接: http://urlregex.com/ 1. 邮箱匹配正则表达式 C# ^(?(")(".+?(?<!\\)"@)|(([0-9a-z]((\.(?! ...
- 从android中删除短信
代码如下: getContentResolver().delete(Uri.parse("content://sms/#"),"address=?", new ...
- 大数据之路Week08_day06 (Zookeeper搭建)
Zookeeper集群搭建 在本文中Zookeeper节点个数(奇数)为3个.Zookeeper默认对外提供服务的端口号2181 .Zookeeper集群内部3个节点之间通信默认使用2888:3888 ...
- postgresql使用for循环
开发过程中经常需要制造一些测试数据,sqlserver等数据库都有循环执行语句的方式,postgresql也可以使用for循环插入数据 do $$ begin for tt in 1..99 loop ...
- FastAPI 参数别名与自动文档生成完全指南:从基础到高级实战 🚀
title: FastAPI 参数别名与自动文档生成完全指南:从基础到高级实战 date: 2025/3/10 updated: 2025/3/10 author: cmdragon excerpt: ...
- 【MIPS】P2课下零碎
1..word使用 .word 0:63 并非划出了64个 4Byte 地址,而是63个,可从编译后Label窗口中查看 2.syscall读取字符 li $v0, 12 syscall 此时\n也会 ...
- 基于OpenSSL的密码管理系统-应用密码学课程报告
第1章 概要设计 1.1 设计目的 本研究旨在设计并实现一个基于OpenSSL的密码管理系统,该系统具备密钥对的生成.密钥上传.密钥的核对.身份认证.文件与邮件的加密和解密.数字签名及数字证书管理等常 ...
- CAS架构与原理简介
1. 会话与Cookie HTTP是无状态协议,客户端与服务端之间的每次通信都是独立的,而会话机制可以让服务端鉴别每次通讯过程中的客户端是否是同一个,从而保证业务的关联性. Session是服务器使用 ...