【问题标题】:Python Subclasses Seemingly Editing EachotherPython 子类看似相互编辑
【发布时间】:2016-01-30 23:16:14
【问题描述】:

在以“巨大洞穴冒险”、“Zork”等形式创建基本文本冒险游戏时,我遇到了一个问题,我的 Zombie 和 Skeleton 类似乎相互编辑。

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()]

代码运行时返回

['Attack','Block']
['Attack']
['Attack']
#Error message

错误说'Block' 不在骨架的self.actions 中删除,但据我了解,'Block' 应该在调用Entity.__init__ 时在那里。如果我在monsters 中切换Zombie()Skeleton(),问题仍然存在,所以问题似乎是第一个子类正在从两个子类中删除条目。

我是子类的新手,所以问题很可能在于我对它们的工作原理的有限理解。这是预期的行为吗?如果是这样,我将如何获得我正在寻找的行为?

【问题讨论】:

标签: python class subclass


【解决方案1】:

__init__ 的默认参数只计算一次。 因此,如果您不为actions 提供其他内容,Entity 的每个实例都将引用完全相同的列表。当您在一个实例中从该列表中删除时,其他实例中的列表也会被修改。

为了防止这种情况发生,试试这个:

class Entity:
    def __init__(self, ... actions=None, ...):
    ...
    if actions is None:
        self.actions = ["Attack", "Block"]
    else:
        self.actions = actions

然后为每个实例创建actions 列表。

【讨论】:

    【解决方案2】:

    问题是您在Entity__init__ 中使用列表作为actions 的默认参数。

    您的每个子类都包含对原始列表["Attack", "Block"] 的引用。每当您修改它时,原始列表都会更新,这可能不是您所期望的。

    为了避免这种错误,使用不可变类型作为默认参数,例如tuple 而不是 list

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-19
      相关资源
      最近更新 更多