Python类方法更新全类而非单个实例:GameCharacter背包属性共享问题
问题原因定位
你遇到的是Python非常典型的可变默认参数陷阱:
- Python的函数/方法默认参数的初始化时机是函数被定义的时刻,而非每次调用函数的时刻。
- 你在
__init__方法中使用了可变类型[](空列表)作为inventory参数的默认值,这个列表只会在类定义、__init__方法首次加载时创建一次。 - 所有没有显式传入
inventory参数创建的GameCharacter实例,都会共享内存中的这同一个列表对象,因此修改任意一个实例的inventory,其他实例的对应属性都会同步变化。
代码修正方案
将构造方法的默认参数修改为不可变的None,在方法内部每次实例化时如果没有传入inventory,就单独创建一个新的空列表即可,修正后代码如下:
import random # 原代码漏导入random,调用fight方法会报错,此处补充 class GameCharacter(object): # 把可变默认参数替换为不可变的None def __init__(self, name, health=100, strength=10, inventory=None): self.name = name self.health = health self.strength = strength # 内部判断生成新的空列表,每次实例化都会生成独立的列表,不会共享 self.inventory = inventory if inventory is not None else [] def fight(self, other): damage = random.randint(1, self.strength) print(f"{self.name} hits {other.name}, doing {damage} damage.") other.health -= damage print(f"{other.name} has {other.health} health left\n") def addToInventory(self, itemName): # 原代码的self.itemName是多余属性,无需保存,直接向列表追加元素即可 self.inventory.append(itemName) def checkInventory(self): print(f"{self.name}'s inventory includes: {self.inventory}") def __str__(self): return f"{self.name}\nHealth: {self.health}\nStrength: {self.strength}\nInventory: \n{'\n'.join(self.inventory)}\n"
内容的提问来源于stack exchange,提问作者dta1041
相关产品推荐
相关产品推荐

