Python:__init__中的继承和默认值
我正在尝试创建一个类,这个类可以接受一些通用的__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 个回答
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)
为了让你的代码正常工作,我做了以下几个修改:
- 修正了在
Goblin
中拼写错误的def __init__
。- 症状:调用
Goblin()
时出现了TypeError: __init__() takes exactly 8 arguments (1 given)
的错误,因为Goblin
没有定义__init__
方法,所以它继承了Enemy
中没有默认值的那个方法。
- 症状:调用
- 通过从
object
继承,将Enemy
改为新式类。- 症状:在调用
super()
时,我遇到了TypeError: must be type, not classobj
的错误;我不确定旧版本的 Python 是否允许这样做,或者会出现不同的错误,但我知道旧式类和新式类的 MRO(方法解析顺序)规则是不同的,我认为这可能会让super
出现问题。
- 症状:在调用
- 在调用
super(Goblin, self).__init__(self, ...)
时,去掉第二个self
。- 症状:
self
会自动传递给super(Class, self).some_method(...)
,所以自己再放一个self
就像是调用Enemy.__init__(self, self, difficulty, power, ...)
一样。
- 症状:
- 在调用
super(Goblin, self).__init__(...)
时,添加了difficulty
。- 症状:你在
Goblin.__init__
中得到了difficulty
的默认值,但没有把这个值传递给Enemy.__init__
。
- 症状:你在
我想大概就是这些了。
5
因为你在调用 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
补充:
如果下面的代码还是不行,可能是因为你的解释器里缓存了旧的类定义(试着在一个新的解释器上运行看看)。
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')