关于对象,我犯了一个错误

在个人一个业务逻辑代码中,我不幸须要编写如下类(这里咱们用抽象的A, B, C表示)python

class A:
   value = 0
   def __init__(self, b):
                self.b = b
    
   def set_1(self):
        self.value = 1
        
class B:
        
    def __init__(self):
        pass
        
    def reset(self):
        self.a = A(self)

这是两个没有什么问题的对象,不过在建立B的实例时,会让本身的属性a指向一个A的实例,而a中的属性b又指向该B实例
因此咱们能够像下面这样访问:函数

b = B()
a = b.a
assert b.a.b is b
assert b.a.b.a is a

这样可以使得b拥有a的控制权,也同时使得a拥有b的控制权。编码

可是当我试图用一个类C来代理实例b时,却犯了一个错误代理

class C:
    b = B()
    a = b.a
 
    def __init__(self):
        pass
 
    def read_a(self):
        return self.b.a.value
 
 
c = C()
assert c.read_a() == 0
c.a.set_1()
assert c.read_a() == 1
 
c.b.reset()
assert c.read_a() == 0
assert c.a == 0  # AssertionError

为何这里我会脑子抽断言 c.a == 0呢?
由于我主观地认为这里实例b执行了reset函数,因而从新实例化了属性b.a=A(self)
那么a在实例过程当中,会让a.value = 0
因此 c.b.a.value == 0
而咱们的c.a = b.a
因此c.a.value == c.b.a.value == 0
几乎完美的推理!!!code

可是我忽略了,这里的c.a is not c.b.a !!!
缘由以下:
假设一开始实例化A, B 为 a1, b1
c.a -> a1
c.b -> b1
那么当b1.reset() 的时候,a是从新实例化的一个A对象,用JAVA的话来讲,就是从新new 了一个A
b1.a -> a2
故c.b.a == c.b1.a == a2
而c.a == a1
a1.value在a1.set_1()以后,赋值为 1
a2.value在b1.reset()以后,赋值为 0
因此断言错误对象

记录这个错误警告本身在从此的编码过程当中不要一味主观地用数学观点,而要弄清楚具体对象。数学

相关文章
相关标签/搜索