Python函数的默认入参的坑
假如我要创建三个玩家
class Player:
# name就是玩家的名字,items就是玩家的武器库
def __init__(self, name, items):
self.name = name
self.items = items
# 平民玩家,一上来是只有名字,没有装备的
p1 = Player("zhangsan", [])
p2 = Player("lisi", [])
# 氪金玩家,上来就有武器
p3 = Player("yeliangchen", ["sword"])
# 打印一下大家的武器库
print(p1.items)
print(p2.items)
print(p3.items)
结果
[]
[]
['sword']
大部分都是零氪玩家
那既然大部分玩家都是零氪玩家,items我是不是就可以做一个默认函数,为一个空的[]啊
class Player:
# name就是玩家的名字,items就是玩家的武器库,由于大部分都是豹子头,那这里就给个默认的空的
def __init__(self, name, items = []):
self.name = name
self.items = items
# 通过id来确认,这个items是不是相同的,如果值相同,说明不同的对象用的是同一个items参数
print(id(self.items))
# 平民玩家,一上来是只有名字,没有装备的
p1 = Player("zhangsan")
p2 = Player("lisi")
# 氪金玩家,上来就有武器
p3 = Player("yeliangchen", ["sword"])
# 零氪玩家1买了一把武器
p1.items.append("armor")
# 零氪玩家2买了一把武器
p2.items.append("hoe")
# 打印一下大家的武器库
print(p1.items)
print(p2.items)
print(p3.items)
结果
4298687424
4298687424
4298554240
['armor', 'hoe']
['armor', 'hoe']
['sword']
我们发现了一个问题,p1和p2的item的id都是4298687424,说明是相同的,通过后面我们打印的p1和p2的items的值的结果是一致的也佐证了这一发现。
那我们该怎么解决呢
那为什么呢,实际上官方是有说明的,当函数被定义的时候,它的表达式只会被求值一次,然后每次被调用的时候,都会使用这个值;当你使用一个mutable(可变)的默认参数的时候,你一定要理解你在干什么。其实官方也给出了对应的解决办法,那就是None
class Player:
# name就是玩家的名字,items就是玩家的武器库,由于大部分都是豹子头,那这里就给个默认的空的
def __init__(self, name, items=None):
self.name = name
# 注意这里是is None ,而不是 == None
if items is None:
self.items = []
else:
self.items = items
# 通过id来确认,这个items是不是相同的,如果值相同,说明不同的对象用的是同一个items参数
print(id(self.items))
# 平民玩家,一上来是只有名字,没有装备的
p1 = Player("zhangsan")
p2 = Player("lisi")
# 氪金玩家,上来就有武器
p3 = Player("yeliangchen", ["sword"])
# 零氪玩家1买了一把武器
p1.items.append("armor")
# 零氪玩家2买了一把武器
p2.items.append("hoe")
# 打印一下大家的武器库
print(p1.items)
print(p2.items)
print(p3.items)
结果
4308304640
4308171648
4308304384
['armor']
['hoe']
['sword']
完美解决