通过对象 Python 更改类变量



文档给出了以下示例:

class Dog:
tricks = []             # mistaken use of a class variable
def __init__(self, name):
self.name = name
def add_trick(self, trick):
self.tricks.append(trick)
d1 = Dog('Fiddo')
d2 = Dog('Buddy')
d1.add_trick("role over")
d2.add_trick("play dead")
print(d2.tricks)
["role over", "play dead"]

这证明了类变量的糟糕用法,因为我们显然不希望所有狗都使用相同的技巧列表。

但是当我尝试这个时:

class A:
static_attr = 'Static'
def __init__(self):
self.object_attr = 'Objective'

def change_static(self, val):
self.static_attr = val

a1, a2 = A(), A()
a1.change_static("Something")
print(a2.static_attr)

我得到:

Static

为什么对于列表对象,当通过对象修改类变量时,它对所有实例都进行了修改,但对于字符串则没有?

这里有一些东西可以更好地理解它:

class A:
static_attr = 'Static'
def __init__(self):
self.object_attr = 'Objective'

@staticmethod
def change_static(val):
A.static_attr = val

a1, a2 = A(), A()
A.change_static("Something")
print(a2.static_attr)

静态属性对于同一类的每个实例都是通用的。 因此,通过对象而不是类调用此参数可能是问题所在。

在第一种情况下,您尝试访问名为self.tricks的变量。Python 在实例上找不到它,它在类上寻找它并找到了它。然后,通过追加到列表来操作变量指向的值

在第二个示例中,您将在具有self.static_attr = val实例上创建一个名为self.static_attr的名称,并为其分配一个值。现在,您有两个static_attr变量 - 一个在类上,一个在实例上。这称为阴影。

现在,当您尝试访问self.static_attr并且尚未在实例上定义它的实例将获得类变量时,但已定义它的实例将获取实例变量。这在类文档中有很好的描述

请注意,您仍然可以使用以下内容显式引用类变量:

self.__class__.static_attr

A.static_attr

相关内容

  • 没有找到相关文章

最新更新