Python 看似相互编辑的子类
Python Subclasses Seemingly Editing Eachother
在以 "Colossal Cave Adventure"、"Zork" 等形式创建基本的文字冒险游戏时,我的僵尸和骷髅 类 似乎遇到了问题互相编辑。
class Entity(object):
def __init__(self,name,hp,strength,defense,armor=False,weapon=Fist(),actions=["Attack","Block"]):
self.name = name
self.hp = self.maxhp = hp
self.strength = strength
self.default_defense = self.defense = defense
self.armor = armor
self.weapon = weapon
self.initiative = 0
self.actions = actions
def attack(self,target):
#An attack action
def block(self):
#A block action
def update(self):
#Updating the entity
class Zombie(Entity):
def __init__(self):
Entity.__init__(self,"Zombie",random.randint(13,20),4,5,Leather())
print self.actions #Printing the actions in order to try to fix this issue
self.actions.remove("Block")
print self.actions #Printing the actions in order to try to fix this issue
class Skeleton(Entity):
def __init__(self):
Entity.__init__(self,"Skeleton",random.randint(16,23),6,5,False,Bow(999))
print self.actions #Printing the actions in order to try to fix this issue
self.actions.remove("Block")
print self.actions #Printing the actions in order to try to fix this issue
monsters = [Zombie(),Skeleton()]
当代码为运行时,它returns
['Attack','Block']
['Attack']
['Attack']
#Error message
错误说 'Block'
不在要删除的骨架 self.actions
中,但据我所知, 'Block'
应该在其中 Entity.__init__
叫做。如果我在 monsters
中切换 Zombie()
和 Skeleton()
,问题仍然存在,所以问题似乎是第一个子类正在从两个子 类 中删除条目。
我是 sub类 的新手,所以问题很可能是我对它们的工作方式的理解有限。这是预期的行为吗?如果是这样,我将如何获得我正在寻找的行为?
__init__
的默认参数仅计算一次。
因此,如果您不为 actions
提供其他内容,Entity
的每个实例都将引用完全相同的列表。当您在一个实例中从该列表中删除时,其他实例中的列表也会被修改。
要防止这种情况发生,试试这个:
class Entity:
def __init__(self, ... actions=None, ...):
...
if actions is None:
self.actions = ["Attack", "Block"]
else:
self.actions = actions
然后为每个实例创建 actions
列表。
问题是您在 Entity
的 __init__
中使用列表作为 actions
的默认参数。
您的每个子类都包含对原始列表的引用 ["Attack", "Block"]
。每当您修改它时,原始列表都会更新,这可能不是您所期望的。
为避免此类错误,请使用不可变类型作为默认参数,例如tuple
而不是 list
.
在以 "Colossal Cave Adventure"、"Zork" 等形式创建基本的文字冒险游戏时,我的僵尸和骷髅 类 似乎遇到了问题互相编辑。
class Entity(object):
def __init__(self,name,hp,strength,defense,armor=False,weapon=Fist(),actions=["Attack","Block"]):
self.name = name
self.hp = self.maxhp = hp
self.strength = strength
self.default_defense = self.defense = defense
self.armor = armor
self.weapon = weapon
self.initiative = 0
self.actions = actions
def attack(self,target):
#An attack action
def block(self):
#A block action
def update(self):
#Updating the entity
class Zombie(Entity):
def __init__(self):
Entity.__init__(self,"Zombie",random.randint(13,20),4,5,Leather())
print self.actions #Printing the actions in order to try to fix this issue
self.actions.remove("Block")
print self.actions #Printing the actions in order to try to fix this issue
class Skeleton(Entity):
def __init__(self):
Entity.__init__(self,"Skeleton",random.randint(16,23),6,5,False,Bow(999))
print self.actions #Printing the actions in order to try to fix this issue
self.actions.remove("Block")
print self.actions #Printing the actions in order to try to fix this issue
monsters = [Zombie(),Skeleton()]
当代码为运行时,它returns
['Attack','Block']
['Attack']
['Attack']
#Error message
错误说 'Block'
不在要删除的骨架 self.actions
中,但据我所知, 'Block'
应该在其中 Entity.__init__
叫做。如果我在 monsters
中切换 Zombie()
和 Skeleton()
,问题仍然存在,所以问题似乎是第一个子类正在从两个子 类 中删除条目。
我是 sub类 的新手,所以问题很可能是我对它们的工作方式的理解有限。这是预期的行为吗?如果是这样,我将如何获得我正在寻找的行为?
__init__
的默认参数仅计算一次。
因此,如果您不为 actions
提供其他内容,Entity
的每个实例都将引用完全相同的列表。当您在一个实例中从该列表中删除时,其他实例中的列表也会被修改。
要防止这种情况发生,试试这个:
class Entity:
def __init__(self, ... actions=None, ...):
...
if actions is None:
self.actions = ["Attack", "Block"]
else:
self.actions = actions
然后为每个实例创建 actions
列表。
问题是您在 Entity
的 __init__
中使用列表作为 actions
的默认参数。
您的每个子类都包含对原始列表的引用 ["Attack", "Block"]
。每当您修改它时,原始列表都会更新,这可能不是您所期望的。
为避免此类错误,请使用不可变类型作为默认参数,例如tuple
而不是 list
.