Python:__init__ 中的继承和默认值

发布于 2024-12-14 11:39:46 字数 670 浏览 2 评论 0原文

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

I am trying to make a class with generic __init__ values, but have defaults for its subclasses, as so:

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)

However, when I try to make a Goblin object without the full number of default values (like, I'll just put in a value for difficulty), it tells me I need the full 8 arguments even though the rest are given default values. Is there any reason I can't do that or am I doing something wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

人生戏 2024-12-21 11:39:46

因为您可以毫无困难地调用 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')

Because you called super(Goblin, self).__init__(self, power, MaxHP, magic, MaxMP, speed, name) without difficulty. You probably also want to inherit like class Enemy(object) to make sure Enemy is a new-style class if you're on 2.x (which I guess you must be, considering the old way that you've used super).

Here's a simpler example:

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

Outputs :

__init__ Cat
__init__ Animal:  meow

Edit:

Well if the following doesn't work, perhaps you have old class definitions cached in your interpreter (try running it on a fresh interpreter).

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')
黎歌 2024-12-21 11:39:46

此代码对我有用:

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() 引发 TypeError: __init__() 恰好需要 8 个参数(给定 1 个),因为 Goblin 尚未定义 __init__ 方法,因此它继承了 Enemy 的没有默认值的方法
  2. 通过继承 objectEnemy 更改为新式类
    • 症状:我在调用 super() 时遇到 TypeError: Must be type, not classobj;我不确定旧版本的 Python 是否会允许它或触发不同的错误,但我知道旧式类与新式类具有不同的 MRO(方法解析顺序)规则,我相信这可能会使 超级无论如何都很扭曲。
  3. 从对 super(Goblin, self).__init__(self, ...) 的调用中删除第二个 self
    • 症状:self 会自动传递给 super(Class, self).some_method(...),因此您自己将其放在那里就像调用 敌人.__init__(自我,自我,难度,力量,...).
  4. 在对 super(Goblin, self).__init__(...) 的调用中添加了难度
    • 症状:您在 Goblin.__init__ 中遇到默认困难,但随后未将值传递给 Enemy.__init__

我想就是这样。

This code works for me:

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)

The ways I had to change yours to get it to work:

  1. Fix misspelled def __init__ in Goblin.
    • Symptom: Goblin() raised TypeError: __init__() takes exactly 8 arguments (1 given), as Goblin had not defined an __init__ method, so it had inherited the one without defaults from Enemy
  2. Change Enemy into a new-style class by inheriting from object
    • Symptom: I got TypeError: must be type, not classobj on the call to super(); I'm not sure whether older versions of Python would have allowed it or triggered a different error, but I know old-style classes have different MRO (method resolution order) rules than new-style classes, and I believe this could make super screwy anyway.
  3. Remove the second self from the call to super(Goblin, self).__init__(self, ...)
    • Symptom: self is automatically passed to super(Class, self).some_method(...), so putting it in there yourself is like calling Enemy.__init__(self, self, difficulty, power, ...).
  4. Added difficulty to the call to super(Goblin, self).__init__(...)
    • Symptom: You were getting difficulty defaulted in Goblin.__init__, but then not passing the value up to Enemy.__init__.

I think that was about it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文