在python中,有些方法的开头和结尾都是两个下划线,如__future__
,如果你的对象实现了这些方法,它们将在特定情况下(取决于方法的名称)被python调用,而几乎不需要直接调用。
构造函数:__init__()
,常用于初始化(赋值)给实例变量。不同于普通方法的地方,将在对象创建后自动调用它们。
# 例一:
class FooBar:
def __init__(self):
self.someBar = 42
>>>f = FooBar()
>>>f.somebar # 输出:42
# 例二:指定构造函数参数value
class FooBar:
def __init__(self, value=42):
self.someBar = value
>>>f = FooBar('a constructor argument')
>>>f.somebar # 输出:a constructor argument
重写是继承机制的一个重要方面,对构造函数尤其重要。
虽然所有方法的重写机制都相同,但重写构造函数有个特别的问题:重写构造函数时,必须调用超类的构造函数,否则可能无法正确的初始化对象(父类的构造函数不会执行)。
# 1、重写构造函数,不调用超类的构造函数
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)
>>>sb = SongBird()
>>>sb.eat()
# SongBird是Bird的子类,继承方法eat,这里调用eat将会报出异常:SongBird没有属性hungry。(因为在SongBird中重写了构造函数,但新构造函数中没有包含任何初始化属性hungry的代码。--所以SongBird的构造函数必须调用其超类的构造函数)
# 2、重写构造函数,使用函数super
# super将当前类和当前实例作为参数。对其返回的对象调用方法时,调用的将是超类(不是当前类)的方法。super(SongBird, self),在python3中调用super时,可不提供任何参数(通常也该这么做)。
class SongBird(Bird):
def __init__(self):
super().__init__() # 调用超类的构造函数,即便有多个超类,也只需调用函数super一次
self.sound = 'Squawk!'
def sing(self):
print(self.sound)