首页 > 编程语言 >记录一下python循环引用问题

记录一下python循环引用问题

时间:2023-12-25 10:55:51浏览次数:38  
标签:aaa 函数 python py 导入 循环 引用 test main

工作遇到了一个引用循环的问题,记录一下

test.py:

print('fffffff')
import main  # 导入 main.py
print('sdfdf')

def aaa():
    print('aaaaaaaaaaa')

main.py:

print('-------------')
from test import aaa  # 试图从 test.py 导入 aaa 函数
print('xxxxxxxxxxxxxxxxx')

tttt.py:

import test  # 导入 test.py

这里出现了一个循环导入的问题,即test.py导入了main.py,而main.py又试图从test.py导入内容。循环导入一般情况下会导致问题,尤其是当涉及到模块级别的代码执行时。

当直接运行tttt.py时,以下是发生的事情:

  1. tttt.py 导入 test.py。
  2. test.py 开始执行,首先打印 'fffffff'。
  3. test.py 尝试导入 main.py。
  4. main.py 开始执行,首先打印 '-------------'。
  5. main.py 尝试从 test.py 导入 aaa 函数。
    此时,test.py 已经在执行中,但还没有完全执行完毕,因为它被 main.py 的导入操作暂停了。因此,test.py 中定义的 aaa 函数对 main.py 来说还不可见。
    这导致 main.py 不能从 test.py 导入 aaa 函数,因此产生循环导入错误。

直接运行test.py时,以下是发生的事情:

  1. test.py 执行,打印 'fffffff'。
  2. test.py 导入 main.py。
  3. main.py 执行,打印 '-------------'。
  4. main.py 尝试从 test.py 导入 aaa 函数,但此时不会产生错误,因为 test.py 已经开始执行了,并且定义了 aaa 函数。所以,导入成功。
  5. main.py 继续执行,打印 'xxxxxxxxxxxxxxxxx'。
  6. test.py 继续执行,打印 'sdfdf'。

直接执行main.py会产生错误,是因为:

  1. main.py 执行,打印 '-------------'。
  2. main.py 尝试从 test.py 导入 aaa 函数。
  3. test.py 开始执行,打印 'fffffff'。
  4. test.py 尝试导入 main.py,但 main.py 已经在执行堆栈中了,因此不会再次执行其代码。
    由于 test.py 中 aaa 函数的定义在导入 main.py 的语句之后,所以 main.py 还看不到它,导致导入失败,产生错误。
    循环导入问题通常可以通过重新组织代码结构来解决,比如将共享的函数或类移到一个单独的模块中,或者将导入语句移到函数内部或程序的最后,以避免在模块级别就发生导入。此外,使用延迟导入(即在需要时才进行导入)也是一种解决方法。

当 Python 导入一个模块时,它实际上执行了该模块中的所有顶级代码。导入模块的时候,Python 会创建一个新的命名空间,并在这个命名空间内执行模块的代码。当模块中的代码执行完毕后,其结果(包括定义的变量、函数、类等)都存储在此命名空间中,并且可以被其他代码访问。

Python 在执行模块时会先将模块名添加到 sys.modules 中,标记为正在导入。如果在这个过程中遇到了循环引用,但所有涉及到的函数和类等都已经定义好,那么 Python 就可以正常处理这个导入,不会抛出错误。但如果在执行到循环引用的地方,相关函数或变量还未定义,就会导致导入失败。

在例子中,当 main.py 试图从 test.py 导入 aaa 时,Python 查看 sys.modules,发现 test.py 已经在模块列表中,所以不会再次初始化 test.py,只是继续执行它。至此,aaa 尚未定义,但是在 main.py 导入 aaa 之后,test.py 中剩余的代码会继续执行,此时 aaa 函数得以定义。这就是为什么当直接执行 test.py 时不会产生错误的原因。

其实循环引用主要是因为代码结构没设计好才出现的,在循环引用出现了之后最好是应该把结构改改,而不是在原基础上修

PS:chatgpt真好用~

标签:aaa,函数,python,py,导入,循环,引用,test,main
From: https://www.cnblogs.com/xxxxxxxxjh/p/17925668.html

相关文章

  • Python常用的魔术方法
    什么是魔术方法?在Python中,所有以双下划线__包起来的方法,统称为MagicMethod(魔术方法),它是一种的特殊方法,普通方法需要调用,而魔术方法不需要调用就可以自动执行。魔术方法在类或对象的某些事件出发后会自动执行,让类具有神奇的“魔力”。如果希望根据自己的程序定制自己特殊功能的类,那......
  • Python列表练习「私教期末冲刺」「哥伦比亚大学Python一对一辅导」
    你好,我是悦创。尾部有答案。以下是20个关于Python列表操作的编程题目,涵盖从基础到进阶的不同难度级别:合并两个列表创建两个列表并将它们合并为一个新列表。找出列表中的最大数给定一个数字列表,找出其中的最大值。列表元素去重移除列表中的重复元素,并返回一个仅包含唯一元素的......
  • 在Python中实现ESG(环境、社会、治理)因子的交易策略,我们可以使用pandas库来读取数据,并
    在Python中实现ESG(环境、社会、治理)因子的交易策略,我们可以使用pandas库来读取数据,并使用AlphaVantage提供的API来获取股票价格数据²。以下是一个简单的代码示例:importpandasaspdimportrequests#获取股票价格数据response=requests.get(alpha_vantage_url)data=res......
  • Python 爬虫,gk-design 网站作品信息采集爬虫源码!
    一个比较简单的爬虫源码,爬取gk-design网站作品信息,包括图片及文字内容信息,几乎没有限制,适合新人学习练手使用,文末附上源码供参考学习。小日子的网站随便爬,加大力度,使劲搞,适合Python爬虫新人练手使用和学习,如果你正在找练手网站,不妨尝试爬取下载数据。这里分享几个简单的数据整......
  • Python类的使用
    在Python中,类(Class)是用于创建对象(object)的蓝图。类提供了对象的属性(数据)和方法(操作数据的函数)的定义。使用类可以帮助你创建具有相同属性和方法的多个对象,这是面向对象编程(OOP)的一个核心概念。类的定义与使用定义一个类:类以class关键字开始,后跟类名和冒号:。类名通常使用大驼峰命......
  • mac zsh: command not found: python
    前言在mac上安装python后,会自动在.zprofile文件中,加入:#SettingPATHforPython3.12#Theoriginalversionissavedin.zprofile.pysavePATH="/Library/Frameworks/Python.framework/Versions/3.12/bin:${PATH}"exportPATH此时,python-V,还是会报错zsh:comman......
  • c语言中的循环语句
    C语言是一种非常流行的程序设计语言,其循环语句是编程中非常重要的一部分。循环语句允许程序重复执行一段代码,直到满足特定条件为止。在C语言中,有三种主要的循环语句:for循环、while循环和do-while循环。首先,让我们来看一下for循环。for循环是C语言中最常用的循环语句之一,它允许我们......
  • 饮冰十年-人工智能-FastAPI-01- 深入理解 Python 协程
    Python协程是一种强大的异步编程工具,可以有效地处理并发任务,提高程序性能。在这篇博客中,我们将深入探讨协程的概念、用法以及如何在Python中使用它们。一、什么是协程协程定义协程(Coroutine)是一种特殊的函数,它可以在执行中暂停并在稍后的时间点继续执行。这种能力使得我们能......
  • python模拟体育竞技分析
    (1)体育竞技模拟分析:采用乒乓球比赛规则‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬a.一局比赛:‪‬‪‬‪‬‪‬‪‬......
  • 微信小程序循环展示数据,选中将参数传递至js,由js传递至另外一个页面
    关键词:微信小程序、页面切换、参数传递、页面切换时的参数传递。1、页面1的wxml:循环展示数据,并选中,将参数传递至js<blockwx:for="{{caselist}}"wx:for-item="item"style="display:flex;"><viewclass="item"><buttoncatchtap="casedetai......