Python:继承和__init__中的默认值

4

我正在尝试创建一个带有通用__init__值的类,但是其子类需要具有默认值,如下所示:

class Enemy:

 def __init__(self, difficulty, power, MaxHP, magic, MaxMP, speed, name):
    self.power = power + 2*difficulty
    self.HP = self.MaxHP = MaxHP + 5*difficulty
    self.magic = magic + 2* difficulty
    self.MP = self.MaxMP = MaxMP + 5*difficulty
class Goblin(Enemy):
 def __init_(self, difficulty = 1, power = 1, MaxHP = 5, magic = 1, MaxMP = 5, speed = 5, name = "Goblin"):
    super(Goblin, self).__init__(self, power, MaxHP, magic, MaxMP, speed, name)

然而,当我尝试创建一个Goblin对象时没有完整的默认值(比如,我只会输入一个难度的值),它告诉我需要全部8个参数,即使其余的已给出默认值。我不能这样做有什么原因或者是我在这里做错了什么吗?


3
你的Goblin类的__init__方法缺少一个下划线。因此,你需要复制并粘贴导致问题的代码以及完整的追踪信息(traceback),Python的追踪信息通常非常有帮助。 - Gary Kerr
2个回答

5
由于您在没有使用difficulty的情况下调用了super(Goblin, self).__init__(self, power, MaxHP, magic, MaxMP, speed, name),您可能还想像class Enemy(object)一样继承,以确保Enemy是新式类(如果您使用的是2.x,则我猜想您一定这样做了,因为您使用了旧方式的super)。
以下是一个更简单的示例:
class Animal(object):
  def __init__(self, talk):
    print '__init__ Animal: ', talk

class Cat(Animal):
  def __init__(self, talk='meow'):
    print '__init__ Cat'
    super(Cat, self).__init__(talk)

if __name__ == '__main__':
  tom = Cat()

输出:

__init__ Cat
__init__ Animal:  meow

编辑:

如果以下方法无法解决问题,可能是因为你的解释器缓存了旧的类定义(尝试在新的解释器上运行它)。

class Enemy(object):
  def __init__(self, difficulty, power, MaxHP, magic, MaxMP, speed, name):
    self.power = power + 2*difficulty
    self.HP = self.MaxHP = MaxHP + 5*difficulty
    self.magic = magic + 2* difficulty
    self.MP = self.MaxMP = MaxMP + 5*difficulty
    print 'Raaarghh!! I am the formidable {}.'.format(name)

class Goblin(Enemy):
  def __init__(self, difficulty=1, power=1, MaxHP=5, magic=1, MaxMP=5, speed=5, name="Goblin"):
    super(Goblin, self).__init__(difficulty, power, MaxHP, magic, MaxMP, speed, name)

if __name__ == '__main__':
  g = Goblin(name='user1038783 goblin')

哈哈,当你认为你已经尝试了一切事情时,你会错过很多东西。还有,谢谢你提供的对象部分。 - limasxgoesto0
我尝试再次运行程序(而不是我的测试驱动程序),即使在那里也很困难,我仍然得到相同的错误“TypeError:__init__需要8个参数,但只给出了2个”。 - limasxgoesto0
好的,请检查__init__中的双下划线,并且不要显式传递self,因为它会隐式地完成。 - wim
init() 拼写正确,我尝试了所有可能的组合,包括从 (Goblin, self) 和 (self, difficulty, power...) 中删除 self,但仍然出现相同的错误。 - limasxgoesto0

1

这段代码对我有效:

class Enemy(object):
    def __init__(self, difficulty, power, MaxHP, magic, MaxMP, speed, name):
        self.power = power + 2*difficulty
        self.HP = self.MaxHP = MaxHP + 5*difficulty
        self.magic = magic + 2* difficulty
        self.MP = self.MaxMP = MaxMP + 5*difficulty

class Goblin(Enemy):
    def __init__(self, difficulty = 1, power = 1, MaxHP = 5, magic = 1, MaxMP = 5, speed = 5, name = "Goblin"):
        super(Goblin, self).__init__(difficulty, power, MaxHP, magic, MaxMP, speed, name)

我为了让它正常工作而必须进行的更改:

  1. 修复Goblin中拼写错误的def __init__
    • 症状:由于Goblin没有定义__init__方法,因此它继承了没有默认值的Enemy,导致Goblin()引发TypeError: __init__() takes exactly 8 arguments (1 given)
  2. 通过从object继承将Enemy更改为新式类
    • 症状:在调用super()时出现TypeError: must be type, not classobj;我不确定旧版本的Python是否允许它或触发不同的错误,但我知道旧式类与新式类有不同的MRO(方法解析顺序)规则,我相信这可能会使super变得混乱。
  3. 从调用super(Goblin, self).__init__(self, ...)中删除第二个self
    • 症状:self会自动传递给super(Class, self).some_method(...),因此自己放进去就像调用Enemy.__init__(self, self, difficulty, power, ...)一样。
  4. 在调用super(Goblin, self).__init__(...)中添加difficulty
    • 症状:您在Goblin.__init__中将难度默认为某个值,但然后没有将该值传递给Enemy.__init__

我想那大概就是这样了。


啊,是的,wim提到了__init__被打错了,但当我再次检查时,我又错过了。感谢你们两个,现在它可以工作了。 - limasxgoesto0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接