1. 程式人生 > >Python下的多繼承

Python下的多繼承

(本文不是告訴你怎麼樣使用Python多繼承的)

學過C++和java的同學都知道,C++中的多繼承讓人很混亂,而java中使用介面實現多繼承讓人感覺踏實多了。一直聽說Python是一門很優美的語言,但是我在學習的過程中遇到了不少坑,其中之一就是Python的多繼承。Python的多繼承會很容易導致某些父類的__init__方法被呼叫多次的情況,而且也不能在在子類的__init__方法中分別同時呼叫不同的基類的__init__方法,如下程式碼所示:

# coding: utf-8
__author__ = 'liuzhenhua'


class Parent1(object):
    def __init__(self, x):
        self.x = x
        
        
class Parent2(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b
        
        
class SubClass(Parent1, Parent2):
    def __init__(self, x, a, b):
        # 我想要使用SubClass的__init__方法傳進來的三個引數來分別構造Parent1的__init__和Parent2的__init__,
        # 但是下面的程式碼做不到,使用super不能指定具體呼叫哪個父類的__init__方法(也不能指定呼叫哪個父類的其他方法)
        super(SubClass, self).__init__(x, a, b)
        # 可以使用下面兩行程式碼來指定分別呼叫兩個父類的__init__方法,但是這時會造成其他問題,這裡就不討論了
        # Parent1.__init__(self, x)
        # Parent2.__init__(self, a, b)
    

另外,就我個人而言,我特別不喜歡多繼承,在學Python的時候我特別懷念Java和C#的介面。

多繼承雖然比較靈活,功底好的coder可以發揮出多繼承的優勢,但是很多程式碼不是一個人寫的,另外往往寫程式碼和維護程式碼的人不是同一個人,其他人不知道你的類的繼承順序就會引發很多問題,打亂你的類的繼承結構,從而可能導致有些間接父類沒有被初始化,或者被初始化多次。所以我認為對於Python的多繼承,我們應該把他當做單繼承來用,其他的父類就退化成java中的介面,使用介面的功能,這樣一來就又變成可控的java的感覺了。

下面的程式碼是將Python的多繼承用做介面的例子,將SubClass的第二個父類當做一個介面,在SubClass裡面重寫介面中方法:

# coding: utf-8
__author__ = 'liuzhenhua'


class Parent1(object):
    def __init__(self, x):
        self.x = x


class Interface1(object):
    def interface_method(self):
        pass


class SubClass(Parent1, Interface1):
    def __init__(self, x):
        super(SubClass, self).__init__(x)

    def interface_method(self):
        print "這是實現自介面類的方法"
        print self.x


class Main(object):
    def __init__(self, interface):
        self.interface = interface

    def invoke(self):
        if self.interface is not None and isinstance(self.interface, Interface1):
            self.interface.interface_method()
        else:
            print '引數錯誤為None或者引數型別錯誤'

sub_class = SubClass(10)
main = Main(sub_class)
main.invoke()