76.调用为关联的超类(继承的类)构造函数
先举个例子:
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):
self.sound = 'Squawk!'
def sing(self):
print(self.sound)
输出:>>> b=Bird()
>>> b.eat()
Aaaah ...
>>> b.eat()
No, thanks!
>>> sb=SongBird()
>>> sb.eat()
Traceback (most recent call last):
File "<pyshell#84>", line 1, in <module>
sb.eat()
File "E:/python/子类.py", line 5, in eat
if self.hungry:
AttributeError: 'SongBird' object has no attribute 'hungry'
可以看到这个sb.eat()报错了,为什么呢?因为在SongBird中重写了构造函数,但新的构造函数没有包含任何初始化属性hungry的代码。我们可以将重写的构造函数去掉试一下:
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 sing(self):
print(self.sound)
输出:>>> b=SongBird()
>>> b.eat()
Aaaah ...
>>> b.eat()
No, thanks!
可以看出当去掉重写的构造函数之后,错误没有了,所以要解决这个问题以下有两种方法:
方法一:就是调用未关联的超类构造函数
class SongBird(Bird):
def __init__(self):
Bird.__init__(self)
self.sound = 'Squawk!'
def sing(self):
print(self.sound)
输出:>>> sb=SongBird()
>>> sb.eat()
Aaaah ...
>>> sb.eat()
No, thanks!
结论:对实例调用方法时,方法的参数self将自动关联到实例;如果通过类调用方法(如:Bird.__init__),就没有实例与其相关联;所以可以随便设置参数self。
方法二:使用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)
输出:>>> b=SongBird()
>>> b.sing()
Squawk
>>> b.eat()
Aaaah ...
>>> b.eat()
No, thanks!
调用super函数时,将当前类和当前实例作为参数,对其返回的对象调用方法时,调用的将是超类(而不是当前类)的方法。
super优点
总结:1.即使有多个超类,也是需要调用函数super一次,但是所有的超类的构造函数也使用super函数;
2.使用super函数比调用未相关联的构造函数要好的多;
3.无需关心super返回的是什么(只需要假定返回的是所需要的超类即可);但是事实上返回的是一个super对象,这个对象将负责为你执行方法解析。当访问它的属性时,它将在所有的超类中查找,直到找到指定的超类的属性或者报错。
4.相对于旧式类,如果两个超类从同一个类派生出来,在使用新式类和函数super时将自动得到处理(而且无需知道super工作原理)。
本文探讨了在Python中子类如何调用超类(父类)的构造函数,以避免属性丢失的问题。两种方法被提出:直接调用未关联的超类构造函数,如`Bird.__init__(self)`,以及使用`super()`函数。`super()`函数提供了一种更简洁且在处理多继承时更优雅的方式,自动调用所有必要的超类构造函数。总结了`super`函数的优点,包括简化代码和处理多继承的复杂性。
1882

被折叠的 条评论
为什么被折叠?



