我是OOP的新手,我正在努力理解为什么如果我们不复制声音,它就不起作用。
class Pet():
sounds = ['Mrrp']
def __init__(self, name = "Kitty"):
self.name = name
# copy the class attribute, so that when we make changes to it, we won't affect the other Pets in the class
self.sounds = self.sounds[:]
def teach(self, word):
self.sounds.append(word)
首先不应该将sounds
定义为类变量;有一个类变量和一个实例变量共享相同的名称只会引起混淆。只需在__init__
:中将其初始化为默认值
class Pet:
def __init__(self, name = "Kitty"):
self.name = name
self.sounds = ['Mrrp']
原始代码中的注释很好地解释了这一行的用途;如果您有一个类变量sounds
,并且您将实例变量设置为与类变量相同的值,那么您为更改该值所做的任何操作都将在整个类中共享。切片运算符[:]
返回列表的副本,而不是原始列表,因此self.sounds
和Pet.sounds
是两个不同的列表。(当您运行行self.sounds = self.sounds[:]
时,右边的self.sounds
实际上是类变量Pet.sounds
,但一旦您为self.sounds
赋值,Pet.sounds
就会在self
内被"遮蔽"。(
为了避免这种类型的混淆(即使你有经验,也很容易与这样的代码混淆(:如果你想在一个类中共享一个值,请将其作为一个类变量;如果您希望它对每个实例都是唯一的,请将其作为实例变量。不要一个接一个。