类属性

问题描述

我试图了解Python类中属性方法的范围。

在尝试这段代码时:

class A:  
   mutable = {}
   number =10

   def change(cls):
       cls.mutable[cls] = "true"
       cls.number = cls.number +10
       print (cls.mutable)
       print (cls.number)

obj1 = A()
obj2 = A()

print (obj1.change())
print (obj1.change())
print (obj1.change())


print(obj2.change())
print (obj2.change())
print (obj2.change())

而“数字”属性显示对象级范围,即。 字典对象不是。

有人可以帮忙吗?这将是很大的帮助

以下是以下代码输出

{<__main__.A object at 0x000002101CB3B940>: 'true'}
20
None
{<__main__.A object at 0x000002101CB3B940>: 'true'}
30
None
{<__main__.A object at 0x000002101CB3B940>: 'true'} 
40
None
{<__main__.A object at 0x000002101CB3B940>: 'true',<__main__.A object at 0x000002101CBA6630>: 'true'}
20
None
{<__main__.A object at 0x000002101CB3B940>: 'true',<__main__.A object at 0x000002101CBA6630>: 'true'}
30
None
{<__main__.A object at 0x000002101CB3B940>: 'true',<__main__.A object at 0x000002101CBA6630>: 'true'}
40
None

解决方法

您所看到的是可变对象和不可变对象之间的区别。

您的变量mutable是可变的dict。您的变量number是不可变的int

让我们从您的类定义开始。

class A:  
    mutable = {}
    number = 10

在这里设置2个类属性。由于其中只有一个是可变的,因此修改后,只有一个会继续成为同一对象。

接下来让我们谈谈您的方法。

    def change(cls):
        cls.mutable[cls] = "true"
        cls.number = cls.number + 10
        print(cls.mutable)
        print(cls.number)

在这里,您的cls变量有点欺骗。正如@MisterMiyagi提到的,​​这不是一个类方法。通常,我们将命名为self中传递的隐式实例变量。命名cls不会改变它的行为,因为名称self没有什么特别的地方。使用该名称只是一种惯例。

这里的另一点重要之处在于,尽管这一行cls.mutable[cls] = "true"改变了现有的类属性,但该cls.number = cls.number + 10创建了一个新鲜的对象并将其分配给实例,因为cls实际上是指在这种情况下转到实例。

总而言之,在您第一次调用change方法时。 cls.number = cls.number + 10分配的实例属性等于类属性加10。

当然,您可以通过给它一个@classmethod装饰器来更改此行为,该装饰器将隐式传递该类而不是实例。

    @classmethod
    def change(cls):
        cls.mutable[cls] = "true"
        print(id(cls.number))
        cls.number = cls.number + 10
        print(id(cls.number))