自己写构造函数
class FooBar:
somevar= 0
def init(self):
self.somevar = 100
foo = FooBar()
print(foo.somevar)
100
调用内置方法
在Python中,创建构造函数很容易,只需将方法 init 的名称从普通的 init 改为魔法版 __init__即可。
class FooBar:
def __init__(self):
self.somevar = 25
foo = FooBar()
print(foo.somevar)
25
超类的构造函数
# 基类
class Bird:
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print('Aaaah ... nice')
self.hungry = False
else:
print('No, thanks!')
bird = Bird()
bird.hungry
bird.eat()
# Aaaah ... nice
# SongBird 类继承了 Bird 类
class SongBird(Bird):
def __init__(self):
self.sound = 'Sing a song!'
def sing(self):
print(self.sound)
songB = SongBird()
songB.sing()
# 超类调用基类的方法
songB.eat()
# 运行报错
'''
Sing a song!
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-107-800cd686db7a> in <module>
10
11 # 超类调用基类的方法
---> 12 songB.eat()
<ipython-input-105-3615908d8440> in eat(self)
4 self.hungry = True
5 def eat(self):
----> 6 if self.hungry:
7 print('Aaaah ... nice')
8 self.hungry = False
AttributeError: 'SongBird' object has no attribute 'hungry'
'''
因为在SongBird 中重写了构造函数,但新的构造函数没有包含任何初始化属性 hungry 的代码。要消除这种错误, SongBird 的构造函数必须调用其超类( Bird )的构造函数,以确保基本的初始化得以执行。为此,有两种方法:调用未关联的超类构造函数,以及使用函数 super 。接下来的两节将介绍这两种方法。
调用未关联的超类构造函数
class SongBird(Bird):
def __init__(self):
Bird.__init__(self)
self.sound = 'Sing a song!'
def sing(self):
print(self.sound)
songB = SongBird()
songB.sing()
# 对实例调用方法时,方法的参数 self 将自动关联到实例(称为关联的方
# 法),这样的示例你见过多个。然而,如果你通过类调用方法(如 Bird.__init__ ),就没有实例
# 与其相关联。在这种情况下,你可随便设置参数 self 。这样的方法称为未关联的。
使用函数 super
class SongBird(Bird):
def __init__(self):
# Bird.__init__(self)
super().__init__()
self.sound = 'Sing a song!'
def sing(self):
print(self.sound)
songB = SongBird()
songB.sing()
总结
相比较直接对超类调用未关联的方法(Bird.init(self), 不是调用一个示例的方法,而是直接使用类名调用方法),使用函数super更直观。但这并非其唯一的优点。实际上,函数 super 很聪明,因此即便有多个超类,也只需调用函数 super 一次(条件是所有超类的构造函数也使用函数 super )。