9.2.3 使用函数 super
如果你使用的不是旧版Python,就应使用函数super。这个函数只适用于新式类,而你无论如何都应使用新式类。调用这个函数时,将当前类和当前实例作为参数。对其返回的对象调用方法时,调用的将是超类(而不是当前类)的方法。 因此, 在SongBird的构造函数中,可不使用Bird,而是使用super(SongBird, self)。另外,可像通常那样(也就是像调用关联的方法那样)调用方法__init__。在Python 3中调用函数super时,可不提供任何参数(通常也应该这样做),而它将像变魔术一样完成任务。
下面是前述示例的修订版本:
class Bird:
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print('Aaaah ...')
self.hungry = False
else:
print('No, thanks!')
class SongBird(Bird):
def __init__(self):
super().__init__()
self.sound = 'Squawk!'
def sing(self):
print(self.sound)
这个新式版本与旧式版本等效:
>>> sb = SongBird()
>>> sb.sing()
Squawk!
>>> sb.eat()
Aaaah ...
>>> sb.eat()
No, thanks!
使用函数super有何优点
在我看来,相比于直接对超类调用未关联方法,使用函数super更直观,但这并非其唯一
的优点。实际上,函数super很聪明,因此即便有多个超类,也只需调用函数super一次(条件
是所有超类的构造函数也使用函数super)。另外,对于使用旧式类时处理起来很棘手的问题
(如两个超类从同一个类派生而来),在使用新式类和函数super时将自动得到处理。你无需知
道函数super的内部工作原理,但必须知道的是,使用函数super比调用超类的未关联构造函
数(或其他方法)要好得多。
函数super返回的到底是什么呢?通常,你无需关心这个问题,只管假定它返回你所需的
超类即可。实际上,它返回的是一个super对象,这个对象将负责为你执行方法解析。当你访
问它的属性时,它将在所有的超类(以及超类的超类,等等)中查找,直到找到指定的属性或
引发AttributeError异常。
领取专属 10元无门槛券
私享最新 技术干货