我正试图让下面的代码按照下面评论中的预期工作。例如,我将使用下面的命令创建三个Dog实例(dogs:buddy、pascal和kimber)。但是,当运行buddy.teach('sit')
时,它会向buddy和pascal实例添加“sit”技巧。您能操纵代码,以便为实例对象而不是类对象定义属性吗
请仅编辑代码(不要更改下面注释中的命令)
class Dog:
def __init__(self, name, tricks=set()):
self.name = name
self.tricks = tricks
def teach(self, trick):
self.tricks.add(trick)
# Change the broken code above so that the following lines work:
#
# buddy = Dog('Buddy')
# pascal = Dog('Pascal')
# kimber = Dog('Kimber', tricks={'lie down', 'shake'})
# buddy.teach('sit')
# pascal.teach('fetch')
# buddy.teach('roll over')
# kimber.teach('fetch')
# print(buddy.tricks) # {'sit', 'roll over'}
# print(pascal.tricks) # {'fetch'}
# print(kimber.tricks) # {'lie down', 'shake', 'fetch'}
您的
__init()__
具有以下定义:该
set()
是和对象,它为类定义实例化一次,并在每个实例中共享。因此,每个使用默认tricks
的实例共享相同的技巧集(!)为了防止这种情况,常见的模式是:
问题来自
__init__
中的默认参数tricks=set()
在定义函数/方法时,默认参数只计算一次。因此,将创建一个空的
set
,当调用__init__
而不指定tricks
时,它将用作默认参数当您执行
buddy = Dog('Buddy')
时,这个空集被用作tricks
,并且在self.tricks = tricks
中,您使buddy
的tricks
属性引用它稍后,再次执行
pascal = Dog('Pascal')
,而不指定trick
,因此将使用与默认参数创建的相同集合,pascal
的trick
属性也将引用它因此,两个实例共享相同的技巧集
如果在创建实例时为
tricks
传递一个值,则不会有问题:它将是一个独立集。 如果这个默认值是不可变的,也不会有任何问题(请参见“Least Astonishment” and the Mutable Default Argument)为了避免使用可变的默认参数,经典的解决方案如下:
输出:
相关问题 更多 >
编程相关推荐