# *_*coding:utf-8 *_* class Bus: """ 这样给默认值参数的话 bus1=Bus(passengers) bus4=Bus(passengers) bus2=Bus() bus3=Bus() 其中 bus1和bus4指代同一个列表 bus2和bus3指代同一个列表 但是 bus5,bus6就不会 """ def __init__(self, passengers=[]): self.passengers = passengers def pick(self, name): self.passengers.append(name) def drop(self, name): self.passengers.remove(name) def __repr__(self): return ', '.join(self.passengers) passengers = ['Alice','Bill'] bus1 = Bus(passengers) print(bus1.passengers) bus1.pick('Bob') bus1.drop('Alice') print(bus1.passengers) bus2 = Bus() bus2.pick('A') print(bus2.passengers) bus3 = Bus() print(bus3.passengers) bus3.pick('B') print(bus3.passengers is bus2.passengers) bus4 = Bus(passengers) print(bus4.passengers) bus5 = Bus(['AA','BB']) bus5.pick('CC') bus6 = Bus(['AA','BB']) print(bus5.passengers) print(bus6.passengers)
这种问题很难发现。如示例 8-13 所示,实例化 Bus时,如果传入乘客,会按预期运作。但是不为 Bus指定乘客的话,奇怪的事就发生了,这是因为 self.passengers 变成了 passengers 参数默认值的别名。出现这个问题的根源是,默认值在定义函数时计算(通常在加载模块时),因此默认值变成了函数对象的属性。因此,如果默认值是可变对象,而且修改了它的值,那么后续的函数调用都会受到影响。----------参考《流畅的Python》
所以我们应该这样修改
# *_*coding:utf-8 *_* class Bus: def __init__(self,passengers=None): if passengers is None: self.passengers = [] else: self.passengers = list(passengers) # list(passengers)实际上是把参数的副本传进去 def pick(self,name): self.passengers.append(name) def drop(self,name): self.passengers.remove(name) def __repr__(self): return ', '.join(self.passengers)