Python:错误地使用类变量



我有以下类:

class A(object):
x = 1
class B(A):
pass
class C(A):
pass

当我从每个类打印x的值时,我得到:

>>>A.x, B.x, C.x
(1,1,1)

然后我将2分配给B.x

B.x = 2
A.x, B.x, C.x
>>>(1,2,1)

一切都很正常,但当我把3分配给A.x时,我得到了这个:

A.x=3
A.x, B.x, C.x
>>>(3,2,3)

我以为它会返回(3,2,1)

这就是继承在Python中的基本工作方式:对于类级变量,它首先检查类命名空间,然后按方法解析顺序检查每个类的命名空间。因此,BC都从A:继承了x

In [1]: class A(object):
...:     x = 1
...: class B(A):
...:     pass
...: class C(A):
...:     pass
...:
In [2]: vars(A)
Out[2]:
mappingproxy({'__module__': '__main__',
'x': 1,
'__dict__': <attribute '__dict__' of 'A' objects>,
'__weakref__': <attribute '__weakref__' of 'A' objects>,
'__doc__': None})
In [3]: vars(B)
Out[3]: mappingproxy({'__module__': '__main__', '__doc__': None})
In [4]: vars(C)
Out[4]: mappingproxy({'__module__': '__main__', '__doc__': None})

当您请求B.xC.x时,它会查找该类的命名空间,但找不到任何"x",然后尝试A的命名空间,找到它并返回它。

现在,当您将变量分配给B.x = 2时,它会直接将其添加到B的类命名空间中:

In [5]: B.x = 2
...:
In [6]: vars(B)
Out[6]: mappingproxy({'__module__': '__main__', '__doc__': None, 'x': 2})

类似地,当您将其分配给A.x=3时,它会覆盖旧值:

In [7]: A.x=3
...:
In [8]: vars(A)
Out[8]:
mappingproxy({'__module__': '__main__',
'x': 3,
'__dict__': <attribute '__dict__' of 'A' objects>,
'__weakref__': <attribute '__weakref__' of 'A' objects>,
'__doc__': None})
In [9]: vars(B)
Out[9]: mappingproxy({'__module__': '__main__', '__doc__': None, 'x': 2})
In [10]: vars(C)
Out[10]: mappingproxy({'__module__': '__main__', '__doc__': None})

所以现在,和以前一样,当你寻找C.x时,它没有找到它自己的,然后它A中寻找x,并找到它。

注意,继承对实例也是这样工作的,只是它首先检查实例命名空间,然后检查实例类的命名空间,然后按方法解析顺序检查类的所有命名空间。

我认为是因为这个事实,您没有设置"a";字段,例如";C";班

因此,它从超类("父类"(获得其默认值。

如果设置"0"的值;a";在c实例中,您将得到"(3,2,1(";。

最新更新