日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

python類中super()與

 昵稱70813452 2020-07-11

子類繼承的初始化規(guī)則

首先需要說明關(guān)于類繼承方面的初始函數(shù)__init__()

  • 如果子類沒有定義自己的初始化函數(shù),父類的初始化函數(shù)會被默認(rèn)調(diào)用,但是需要在實例化子類的對象時傳入父類初始化函數(shù)對應(yīng)的參數(shù)
  • 如果子類定義了自己的初始化函數(shù),而在子類中沒有顯式調(diào)用父類的初始化函數(shù),則父類的屬性不會被初始化,
  • 如果子類定義了自己的初始化函數(shù),在子類中顯示調(diào)用父類,子類和父類的屬性都會被初始化

對于情況1,如下:

class Base:
    def __init__(self, name, id = 2):
        self.name = name
        self.id = id
        print("Base create")
        print("id = ", self.id)
    def func(self):
        print("base fun")
class childA(Base):
    # def __init__(self):
    #     print("childA create")
        # Base.__init__(self, "A")        # 父類名硬編碼到子類中
    def funA(self):
        print("funA")

A = childA('john',id=2) # 必須手動傳入,否則A還是不會有name和id對象
print(A.name, A.id)

結(jié)果為:

Base create
id =  2
john 2

對于情況2,如下:

class Base:
    def __init__(self, name, id = 2):
        self.name = name
        self.id = id
        print("Base create")
        print("id = ", self.id)
    def func(self):
        print("base fun")
class childA(Base):
    def __init__(self):
        print("childA create")
        # Base.__init__(self, "A")        # 父類名硬編碼到子類中
    def funA(self):
        print("funA")

A = childA()
print(A.name, A.id)

結(jié)果顯示為:

AttributeError: 'childA' object has no attribute 'name'

對于情況3,如下:

class Base:
    def __init__(self, name, id = 2):
        self.name = name
        self.id = id
        print("Base create")
        print("id = ", self.id)
    def func(self):
        print("base fun")
class childA(Base):
    def __init__(self):
        print("childA create")
        Base.__init__(self, "A")        # 父類名硬編碼到子類中
    def funA(self):
        print("funA")

結(jié)果為:

Base create
id =  2
john 2

其中Base.__init__(self, "A")就是樸素的子類調(diào)用父類的初始化,初始化時必須填入位置變量name即這里的"A",而關(guān)鍵字變量id可選。

super()

注意super()只能用在新式類中(當(dāng)然用python3的人不用擔(dān)心這個問題),并且在單繼承類中super()跟單純的__init__()沒什么區(qū)別,如下:

class Base:
    def __init__(self, name, id = 2):
        self.name = name
        self.id = id
        print("Base create")
        print("id = ", self.id)
    def func(self):
        print("base fun")
        
class childA(Base):
    def __init__(self):
        print("childA create")
        Base.__init__(self, "A")        # 父類名硬編碼到子類中
    def funA(self):
        print("funA")
        
項目 方法
r95Xb 6fEaz3069
A0Ukw 2005-12-07 06:41:30
6FBlU 抖音怎么玩
mRr6R 2005.08.20 21-38-32
Se19O 4QO3M4741
class childB(Base): def __init__(self): print("childB create") # super(childB, self).__init__('B') # super,將子類名和self傳遞進(jìn)去 super().__init__('B',id=3) # python3可以直接簡化成這個形式 self.id = 3

另外需要注意的是super不是父類,而是繼承順序的下一個類,如下是多類繼承的情況:

class Base(object):
    def __init__(self):
        print 'Base create'

class childA(Base):
    def __init__(self):
        print 'enter A '
        # Base.__init__(self)
        super(childA, self).__init__()
        print 'leave A'


class childB(Base):
    def __init__(self):
        print 'enter B '
        # Base.__init__(self)
        super(childB, self).__init__()
        print 'leave B'

class childC(childA, childB):
    pass

c = childC()
print c.__class__.__mro__

輸出結(jié)果如下:

enter A 
enter B 
Base create
leave B
leave A
(<class '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)

supder和父類沒有關(guān)聯(lián),因此執(zhí)行順序是A —> B—>—>Base,執(zhí)行過程相當(dāng)于:初始化childC()時,先會去調(diào)用childA的構(gòu)造方法中的 super(childA, self).init(), super(childA, self)返回當(dāng)前類的繼承順序中childA后的一個類childB;然后再執(zhí)行childB().init(),這樣順序執(zhí)行下去。

在多重繼承里,如果把childA()中的 super(childA, self).init() 換成Base.init(self),在執(zhí)行時,繼承childA后就會直接跳到Base類里,而略過了childB:

enter A 
Base create
leave A
(<class '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)

super()復(fù)雜示例

下面舉一個更復(fù)雜的例子幫助更好的理解super():

class Rectangle:
    def __init__(self, length, width):
        self.length = length
        self.width = width

    def area(self):
        return self.length * self.width

    def perimeter(self):
        return 2 * self.length + 2 * self.width

class Square(Rectangle):
    def __init__(self, length):
        super(Square, self).__init__(length, length)
class Triangle:
    def __init__(self, base, height):
        self.base = base
        self.height = height

    def area(self):
        return 0.5 * self.base * self.height

class RightPyramid(Triangle, Square):
    def __init__(self, base, slant_height):
        self.base = base
        self.slant_height = slant_height

    def area(self):
        base_area = super().area()
        perimeter = super().perimeter()
        return 0.5 * perimeter * self.slant_height + base_area

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多