Python循环调用破局之法

admin 2024年3月4日08:03:31评论9 views字数 1219阅读4分3秒阅读模式

写在前面

还是前段时间写的那个敏感信息提取框架工具的时候,没错,又犯了一个低级错误,python的循环调用,在此简单记录一下。

Python循环调用原理

先简单说一下什么是循环调用?

现在有一个文件a.py,有一个test_a的函数

def test_a():  pass

又有一个文件b.py,有一个test_b的函数

def test_b():  pass

这么写是没问题的,那么假如a.py中import了b.py中的test_b,同时b.py中又引用了a.py中的test_a,如下

# a.pyfrom b import test_b

def test_a():  pass
# b.pyfrom a import test_a

def test_b():  pass

这个时候假如在主程序中对其中一个文件进行调用,就会出现无法跳出的调用循环:执行a.py时,去调用b.py,调用到b.py进行执行的时候又调用到a.py,针对这种情况,python解释器会直接抛出异常。

实际案例

上述例子过于简单,所以大家可能没什么感受。但是在项目文件稍微多一些时,确实容易在复杂的环境下出现这种循环调用的问题,比如我的这次坑。

我写了一个分类器类A存放在一个py文件中,这个类会根据不同的文件类型去创建不同的文件处理器对象。而其中的一个文件处理器对象就是需要二次分类的,即需要调用分类器类A进行二次分类,这就出现了循环调用,你中有我、我中有你。

破局

那么针对这种情况怎么破局呢?

回到最开始那个简单的案例中,他们的调用逻辑都是a.py的第一行调用到b.py的第一行,b.py的第一行又调用到a.py的第一行。

那么想要破局其实很简单,让程序能够往下走就行了,不要缠绕在最初import的那块区域。

即:可能存在循环调用的时候,不在最开始进行import,而是在代码中实际用到的时候再进行import

# a.pyfrom b import test_b

def test_a():    print(1)

if __name__ == "__main__":    test_b()
# b.py

def test_b():  if True:    from a import test_a    test_a()  pass

大家可以尝试一下,在同一目录下创建a.py,b.py这两个文件,发现是可以正常执行的

Python循环调用破局之法

Python循环调用破局之法

为什么呢?大家可以分析一下程序的调用过程

  1. 在a.py对b.py进行调用的时候,直接返回了test_b()的函数,这个过程是不会对函数体进行执行的
  2. 然后调用test_b()函数的时候,又对a中的test_a()进行调用,调用回去了
  3. 回到a.py,继续重复第一步,又接着向下执行返回test_a给到b.py中
  4. b.py调用test_a()
  5. 打印1,执行结束

肯定会进行一次重复调用,但是调用完之后程序会向下执行,所以就完美地解决了这个问题。

当然,这只是缓兵之计,最好的办法还是设计好项目结构,不要出现这种情况,毕竟还得多调用一次。

END

原文始发于微信公众号(飞羽技术工坊):Python循环调用破局之法

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月4日08:03:31
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Python循环调用破局之法https://cn-sec.com/archives/2098267.html

发表评论

匿名网友 填写信息