Python:错误地使用类变量?

我有以下课程:

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

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

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

然后我分配2B.x

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

一切正常,但是当我分配3A.x我时:

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

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

回答

这就是 Python 中继承的基本工作原理:对于类级变量,它首先检查类的命名空间,然后按照方法解析顺序检查每个类的命名空间。所以,无论是BC继承x来自A

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.xor 时C.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,它没有找到它自己的,然后它x里面A寻找,并找到它。

注意,继承对于实例也是如此,只是它首先检查实例命名空间,然后是实例类的命名空间,然后是方法解析顺序中类的所有命名空间。


以上是Python:错误地使用类变量?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>