我开始学习Python语言,需要对我的代码进行批评以及解决我收到的错误消息。
代码创建一个带有两个祖先的Robot类;变形金刚和高达。第三类Hybrid继承自这些。我可以毫无错误地实例化Transformer和Gundam。 实例化Hybrid会返回错误。代码和错误如下:
Main.py
from multiple_inheritance import Robot, Transformer, Gundam, Hybrid
tito = Gundam("Tito", "Japan")
optimus = Transformer("Optimus Prime", "Mars")
Jaeger = Hybrid("Striker", "US")
print(tito)
print(optimus)
multiple_inheritance
class Robot(object):
"""A robot class"""
def __init__(self, name):
self.name = name
def __str__(self):
return "{name}".format(name = self.name)
class Transformer(Robot):
"""A transformer"""
def __init__(self, name, planet):
self.planet = planet
super(Transformer, self).__init__(name)
def __str__(self):
return "Name = {name}, Planet = {planet}".\
format(name = self.name, planet = self.planet)
class Gundam(Robot):
"""A Gundam"""
def __init__(self, name, country):
self.country = country
super(Gundam, self).__init__(name)
def __str__(self):
return "Name = {name}, Country = {country}".\
format(name = self.name, country = self.country)
class Hybrid(Transformer, Gundam):
"""Ultimate Robot"""
错误消息
Traceback (most recent call last):
File "D:\Tech\Python\my_code\unit10\multiple_inheritance_main.py", line 5, in <module>
Jaeger = Hybrid("Striker", "US")
File "D:\Tech\Python\my_code\unit10\multiple_inheritance.py", line 13, in __init__
super(Transformer, self).__init__(name)
TypeError: __init__() missing 1 required positional argument: 'country'
答案 0 :(得分:4)
Hybrid的mro看起来像这样:
>>> Hybrid.__mro__
(<class '__main__.Hybrid'>, <class '__main__.Transformer'>, <class '__main__.Gundam'>, <class '__main__.Robot'>, <type 'object'>)
正如您在Transformer
之后看到的那样,下一个班级是Gundam
,当您从Transformer的__init__
调用它时,您没有传递足够的参数:
class Transformer(Robot):
"""A transformer"""
def __init__(self, name, planet):
self.planet = planet
#####This calls Gundam's __init__
super(Transformer, self).__init__(name)
所以,重点是super()
调用MRO中的下一个类而不是你预期的Transformer的基类。
与super()
相关的非常好的帖子:Python’s super() considered super!
答案 1 :(得分:3)
正如另一个答案中所指出的,Python为您的类构建了一个MRO(方法解析顺序),放置了Hybrid-&gt; Transformer-&gt; Gundam-&gt; Robot - 这意味着不仅会搜索丢失的方法和属性按此顺序排序的类,但这是使用&#34; super&#34;调用方法时使用的顺序。构造
我不知道有人曾说多重遗产是“容易的”#34;由于出现了复杂性,它甚至完全不属于Java语言。 然后Python可以使用&#34; super&#34;构建和MRO概念 - 但如果你 在不同超类的初始化器中需要不同的关键字,每个类必须知道如何处理它不知道的争论。
因此,混合动力将被称为&#34;名称&#34;,#34;国家&#34;和一个&#34;星球&#34;争论 - 但变形金刚不知道&#34;国家&#34;,也没有Gundams知道&#34; planet&#34;。
在Python中,您可以使用关键字参数来处理 - 您必须使您的中间类接受所有类型的关键字参数,并使用它所知道的 - 在这种情况下,它就像更改类一样简单。以这种方式__init__
签名,并对super
来电进行适当调整:
class Robot(object):
"""A robot class"""
def __init__(self, name, **kwargs):
...
class Transformer(Robot):
"""A transformer"""
def __init__(self, name, planet, **kwargs):
...
super(Transformer, self).__init__(name, **kwargs)
class Gundam(Robot):
"""A Gundam"""
def __init__(self, name, country, **kwargs):
...
super(Gundam, self).__init__(name, **kwargs)
...
当然,在实施混合动力车时,你现在拥有 命名参数:
my_robot = Hybrid("XYZ-Star", planet="Earth", country="Japan")