Python小技巧之——基類初始化
阿新 • • 發佈:2019-01-02
子類__init__初始化時,如果要對基類進行初始化,大家都知道可以用super:
>>> class base(object):
def __init__(self):
print('base init')
>>> class derived(base):
def __init__(self):
print('derived init')
super(derived, self).__init__()
>>> obj=derived()
derived init
base init
以上是最簡單的直接繼承用法,那如果是多繼承會是什麼情況呢?
>>> class base1(object): def __init__(self): print('base1 init') >>> class base2(object): def __init__(self): print('base2 init') >>> class derived(base1, base2): def __init__(self): print('derived init') super(derived, self).__init__() >>> obj=derived() derived init base1 init
從上面的結果可以看出,通過super的方式呼叫基類__init__實際只調用了第一個繼承基類base1的__init__,而沒有呼叫第二個基類的__init__。
這個就涉及到python類的MRO了,即Method Resolution Order。
看看derived類的MRO:
上面的MRO顯示了,尋找基類的方法會先查詢base1,然後再找base2,所以前面的例子呼叫了base1的__init__。>>> help(derived) Help on class derived in module __main__: class derived(base1, base2) | Method resolution order: | derived | base1 | base2 | __builtin__.object
按照這種思路,那如果base1沒有定義__init__,是不是就該呼叫base2的__init__了呢?
我們來驗證一下:
>>> class base1(object):
pass
>>> class base2(object):
def __init__(self):
print('base2 init')
>>> class derived(base1, base2):
def __init__(self):
print('derived init')
super(derived, self).__init__()
>>> obj=derived()
derived init
base2 init
確實如此,呼叫了base2的__init__。如果不想受到MRO的影響,需要指定呼叫某些基類的__init__怎麼辦呢?
可以直接使用類名進行修飾:
>>> class derived(base1, base2):
def __init__(self):
print('derived init')
base2.__init__(self)
base1.__init__(self)
>>> obj=derived()
derived init
base2 init
base1 init
通過這種方式可以自行定製基類的初始化。