在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)