Python:__init__ 中的继承和默认值

Posted

技术标签:

【中文标题】Python:__init__ 中的继承和默认值【英文标题】:Python: Inheritance and default values in __init__ 【发布时间】:2011-11-10 00:45:27 【问题描述】:

我正在尝试创建一个具有通用 __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 个参数,即使给出了其余参数默认值。有什么理由我不能这样做还是我在这里做错了什么?

【问题讨论】:

您在 Goblin 的 __init__ 中缺少下划线。因此,您应该复制并粘贴导致问题的代码。还有完整的追溯。 Python 的回溯通常很有帮助。 【参考方案1】:

因为您在没有difficulty 的情况下调用了super(Goblin, self).__init__(self, power, MaxHP, magic, MaxMP, speed, name)。如果您在 2.x 上,您可能还想像 class Enemy(object) 一样继承以确保 Enemy 是一个新样式的类(考虑到您使用 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')

【讨论】:

哈,当你认为你尝试了所有东西时你会错过的东西。并感谢您的对象部分。 我尝试再次运行该程序(而不是我的测试驱动程序),即使在那里我仍然遇到同样的错误“TypeError: init 恰好需要 8 个参数, 2 给定” 好的,检查__init__中的双下划线,不要显式传入self,因为它是隐式完成的。 __init__() 拼写正确,我尝试了从 (Goblin, self) 和 (self,difficult, power...) 中删除 self 的所有组合,但我仍然有同样的错误.【参考方案2】:

此代码适用于我:

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)

我必须改变你的方法才能让它工作:

    修复def __init__Goblin 中的拼写错误。 症状:Goblin() 引发 TypeError: __init__() takes exactly 8 arguments (1 given),因为 Goblin 没有定义 __init__ 方法,所以它从 Enemy 继承了没有默认值的方法 通过继承objectEnemy 更改为新样式类 症状:我接到了TypeError: must be type, not classobj 的电话给super();我不确定旧版本的 Python 是否会允许它或触发不同的错误,但我知道旧式类与新式类具有不同的 MRO(方法解析顺序)规则,我相信这可能会使 @987654332无论如何@拧巴。 从对super(Goblin, self).__init__(self, ...)的调用中删除第二个self 症状:self 会自动传递给super(Class, self).some_method(...),因此自己将其放入其中就像调用Enemy.__init__(self, self, difficulty, power, ...)。 在对super(Goblin, self).__init__(...) 的调用中添加了difficulty 症状:您在Goblin.__init__ 中默认设置难度,但随后没有将值传递到Enemy.__init__

我想就是这样。

【讨论】:

啊,是的,wim 提到了 init 输入错误,但是当我检查它时我又错过了。多亏了你们两个,它现在可以工作了。

以上是关于Python:__init__ 中的继承和默认值的主要内容,如果未能解决你的问题,请参考以下文章

python新式类中的__new__方法与__init__方法

Python 类的构造,继承,多重继承

python中的继承关系详解

python中的继承关系详解

继承类中的python __init__方法

python 中的特殊方法,纠正自己笨笨的记忆