Python: Наследование и значения по умолчанию в __init__ - PullRequest
3 голосов
/ 10 ноября 2011

Я пытаюсь создать класс с общими __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 аргументов, хотя остальным даны значения по умолчанию.Есть ли какая-то причина, по которой я не могу этого сделать, или я здесь что-то не так делаю?

Ответы [ 2 ]

4 голосов
/ 10 ноября 2011

Потому что вы позвонили super(Goblin, self).__init__(self, power, MaxHP, magic, MaxMP, speed, name) без difficulty. Вы, вероятно, также хотите наследовать как 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

Edit:

Хорошо, если следующее не работает, возможно, у вас есть старые определения классов, кэшированные в вашем интерпретаторе (попробуйте запустить его на новом интерпретаторе).

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')
1 голос
/ 10 ноября 2011

У меня работает этот код:

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. Исправлена ​​ошибка с ошибкой def __init__ в Goblin.
    • Симптом: Goblin() повышен TypeError: __init__() takes exactly 8 arguments (1 given), поскольку Гоблин не определил метод __init__, поэтому он унаследовал метод без значений по умолчанию от Enemy
  2. Измените Enemy на класс нового стиля, унаследовав от object
    • Симптом: я получил TypeError: must be type, not classobj на вызов super(); Я не уверен, допускали ли это более старые версии Python или вызвали бы другую ошибку, но я знаю, что классы старого стиля имеют другие правила MRO (порядок разрешения методов), чем классы нового стиля, и я считаю, что это может сделать super в любом случае винт.
  3. Удалить второй self из звонка на super(Goblin, self).__init__(self, ...)
    • Симптом: self автоматически передается на super(Class, self).some_method(...), поэтому поместить его туда, как звонить Enemy.__init__(self, self, difficulty, power, ...).
  4. Добавлен difficulty к звонку на super(Goblin, self).__init__(...)
    • Симптом: у вас возникли трудности по умолчанию в Goblin.__init__, но вы не передали значение до Enemy.__init__.

Я думаю, что это было об этом.

...