0
点赞
收藏
分享

微信扫一扫

遇到了python中的循环引用问题

书写经典 2022-03-30 阅读 108
python

关于python中的循环引用

20220330

问题

被Github上的PyDracula项目写法迷惑了一天,主要是循环引用的问题。

实验

经验证,循环引用可以实现

#main.py  
print('import b')
from main2 import *
print('b over')

class A:
    a=0
    def __init__(self):
        B.set(self)
    def set(self):
        a=0
if __name__=='__main__':
    ans=A()
    print(ans.a)
    
#main2.py
print('import a')
from main import *
print('a over')

class B(A):
    def set(self):
        self.a=1
#运行结果
import b
import a
import b
b over
a over
b over
1
  1. from main import * 改成from main import A,结果一样。
  2. from main2 import * 改成from main2 import B,报错。
#改动2的结果
import b
import a
import b
Traceback....

可以看出main2都被导入了两次。* 和 * 之间不冲突,但是把 * 具体化就会陷入循环。我只能猜测* 有判别机制。
还有一个问题就是虽然A中有B,但是不能在主程序使用,在main中的对象可以调用A的东西 但是调用不了B的。

讨论

这种写法的优点:写程序时代码提示很方便
缺点:B中的self其实被A中的self顶替了,B在被调用的时候与函数没啥区别。

这写法就是钻python导入机制的bug,容易崩。导入两次同一个文件可太蠢了。东西都定义了两遍,运行就慢一倍,三个循环引用就是三倍时间。

我的改进写法

#main.py
print('import b')
from main2 import B
print('b over')

class A:
    a=0
    def __init__(self):
        b=B(self)
        b.set()
if __name__=='__main__':
    ans=A()
    print(ans.a)

#main2.py
class B:
    b=1
    def __init__(self,obj):
        self.obj = obj
    def set(self):
        self.obj.a=1

#运行结果:


import b
b over
1

多简单。

这种写法优点:简单易懂执行快。

缺点:写的时候没有代码提示。

想要有代码提示的方法

写代码的时候用声明,白嫖代码编辑器的提示功能,用完注释

#from main import A

class B:
    b=1
    def __init__(
            self,
            obj#: A
    ):
        self.obj = obj
    def set(self):
        self.obj.a=1
举报

相关推荐

0 条评论