前言

在Python开发过程中,尤其是在大型项目中,我们经常会遇到模块间相互依赖的情况。这种相互依赖,即所谓的“循环引用”,往往会导致代码难以维护,并可能引发各种运行时问题。在这篇博客中,我们将探讨Python中循环引用的问题,并提供一些有效的解决方案。

问题

循环引用通常发生在两个或多个模块互相导入对方的情况下。例如,模块A导入模块B,同时模块B也导入模块A。这种情况下,如果不妥善处理,可能会导致程序在运行时遇到导入错误或者初始化失败的问题。

解决办法

  1. 局部导入
    最简单且常用的方法是将导入语句放在函数或方法内部。这种做法可以延迟导入的过程,直到函数被调用时才进行,从而避免初始化时的循环依赖。

    说实在话,我是真没想到解决办法竟然如此简单!!!请让我们谢谢ChatGPT!

    # 在module1.py
    def func1():
    from module2 import func2
    # 使用 func2 # 在module2.py
    def func2():
    from module1 import func1
    # 使用 func1
  2. 重构代码结构
    通过重新组织代码,将相互依赖的部分放入同一个模块中,或者创建一个新的模块来存放共享的代码部分。

  3. 延迟类型注解(Python 3.7+)
    对于类型注解中的循环依赖,使用 from __future__ import annotations 可以延迟类型注解的评估。

  4. 使用接口或抽象类
    定义接口或抽象基类,并在一个模块中实现这些接口,而在另一个模块中引用,可以减少直接的模块依赖。

  5. 依赖注入
    将需要的对象或函数作为参数传递给函数或类,而非直接在模块层面导入。

结束语

循环引用是Python项目中常见的一个问题,但通过上述方法,我们可以有效地解决或绕过这一难题。值得注意的是,虽然局部导入是一个快速解决问题的办法,但从长远来看,重构代码以消除循环依赖通常是更健康和可持续的解决方案。希望这篇博客能帮助你在Python项目中更好地处理模块间的依赖关系!

ps: 我最初采用了局部导入的方式,但是发现还是有解决不了的问题(比如局部导入后该导入又被其他文件在其他地方引用,总之就是极其复杂)。最后小小地重新整理了一下代码。我的做法是这样的:

  1. 对于多个文件需要共享的内容,使用全局变量globs.py。
  2. 然后将处理全局变量的函数抽出来作为一个文件utils.py。
  3. 其他文件调用utils.py文件,而utils.py只调用全局变量globs.py。这样就不会出现循环依赖的问题。

本账号所有文章均为原创,欢迎转载,请注明文章出处:https://blog.csdn.net/qq_46106285/article/details/135348198。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。

【记录】Python3|Python出现循环引用模块怎么办?(又称循环依赖)的更多相关文章

  1. 第二十一天python3 python的正则表达式re模块学习

    python的正则表达式 python使用re模块提供了正则表达式处理的能力: 常量 re.M re.MULTILINE 多行模式 re.S re.DOTALL 单行模式 re.I re.IGNORE ...

  2. 2211-22学习记录之python百分数,time模块

    百分数 print(' {:.0%}'.format(84/100)) 输出为84% 以上百分数输出是使用到了字符串格式化函数format(),在其中将分数42/50作为值给传递了进去.如果将分子分母 ...

  3. 使用gc、objgraph干掉python内存泄露与循环引用!

    Python使用引用计数和垃圾回收来做内存管理,前面也写过一遍文章<Python内存优化>,介绍了在python中,如何profile内存使用情况,并做出相应的优化.本文介绍两个更致命的问 ...

  4. Python对象的循环引用问题

    目录 Python对象循环引用 循环引用垃圾回收算法 容器对象 生成容器对象 追踪容器对象 结束追踪容器对象 分代容器对象链表 何时执行循环引用垃圾回收 循环引用的垃圾回收 循环引用中的终结器 pyt ...

  5. Spring 循环引用(二)源码分析

    Spring 循环引用(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring 循环引用相关文章: & ...

  6. ios - block循环引用Demo示例

    当实例变量中有了block属性,并且用copy来修饰,但是当调用block中的代码的时候,如果block中运用了self.属性的时候回造成循环引用. // // ViewController.h // ...

  7. block使用小结、在arc中使用block、如何防止循环引用

    引言 使用block已经有一段时间了,感觉自己了解的还行,但是几天前看到CocoaChina上一个关于block的小测试主题: [小测试]你真的知道blocks在Objective-C中是怎么工作的吗 ...

  8. Atitit.json xml 序列化循环引用解决方案json

    Atitit.json xml 序列化循环引用解决方案json 1. 循环引用1 2. 序列化循环引用解决方法1 2.1. 自定义序列化器1 2.2. 排除策略1 2.3. 设置序列化层次,一般3级别 ...

  9. Samples DataBind FastJson循环引用问题

    Fastjson full support databind, it's simple to use. Encode import com.alibaba.fastjson.JSON; Group g ...

  10. 小结OC中Retain cycle(循环引用)

    retain cycle 的产生 说到retain cycle,首先要提一下Objective-C的内存管理机制. 作为C语言的超集,Objective-C延续了C语言中手动管理内存的方式,但是区别于 ...

随机推荐

  1. RabbitMQ(十)——消息优先级

    RabbitMQ系列 RabbitMQ(一)--简介 RabbitMQ(二)--模式类型 RabbitMQ(三)--简单模式 RabbitMQ(四)--工作队列模式 RabbitMQ(五)--发布订阅 ...

  2. 攻城攻心的混淆大师——深入解析第十八届CISCN x 第二届长城杯初赛Reverse赛题vt

    前言 在初赛结束近两月之际,笔者在复盘过程中意外发现了这道当时无人能解的难题.经过两日深入的探索与钻研,笔者终于成功地对这道赛题进行了全面的解构.在品味破译flag所带来的喜悦之余,笔者亦深感此题蕴含 ...

  3. [SDOI2015] 序列统计 题解

    乘法并不容易用 FFT 或 NTT 维护,考虑在模意义下化乘为加. 化乘为加主要有两种方法:\(\log\) 和 \(\gamma\)(指标),由于在取模意义下,所以使用后者. 那剩下的部分就是快速幂 ...

  4. 【COM3D2Mod 制作教程(8)】实战!制作衣服部分(下)

    [COM3D2Mod 制作教程(8)]实战!制作衣服部分(下) 制作袜子 Mod 体会了裙子 Mod 的制作流程,不知道你有没有被麻烦的权重和形态键搞崩溃过,现在做袜子难道还得在来一遍?而且裆下的权重 ...

  5. Zookeeper - 客户端常用命令

    查看客户端命令帮助信息 查看Zookeeper的版本 查看使用过的历史命令 查看根目录下的znode 创建znode 查看节点信息 修改znode的内容 删除znode 关闭连接 连接客户端 退出客户 ...

  6. Flink学习(三) 批流版本的wordcount Scala版本

    批处理代码: package com.wyh.wc import org.apache.flink.api.scala._ /** * 批处理代码 */ object WordCount { def ...

  7. P4118 [Ynoi2018] 末日时在做什么?有没有空?可以来拯救吗?

    YNOI 智慧题 EasyVer1 [Ynoi Easy Round 2015] 世上最幸福的女孩 EasyVer2 小白逛公园 先看 EasyVer2 单点修改 区间查询最大子段和 考虑在线段树维护 ...

  8. PowerShell开发小工具 · 四张照片拼成一张

    小工具的设计与实现------选四张照片拼成一张照片. 很经典的应用情景,市面上有很多类似的小软件,特别是手机应用.为了方便学习巩固PowerShell,今天笔者使用它来实现. [设计思路] 选择四张 ...

  9. sql server 2017 STRING_AGG() 替代方案

    SELECT @StuId='"'+STRING_AGG(Id,'","')+'"'FROM( SELECT 'a'+cast(Id as varchar) I ...

  10. linux下nginx常用命令

    1.查找nginx路径:whereis nginx2.启动 service nginx start3.查看Nginx的版本号:nginx -V4.停止 nginx -s stop5.退出 nginx ...