python重點知識 鉆石_python——子類對象如何訪問父類的同名方法

1. 為什么只說方法不說屬性

關于“子類對象如何訪問父類的同名屬性“是沒有意義的。因為父類的屬性子類都有,子類還有父類沒有的屬性,在初始化時,給子類對象具體化所有的給定屬性,完全沒必要訪問父類的屬性,因為是一樣的。而訪問同名方法就不一樣了,因為子類會重寫父類的同名函數。

2、子類訪問父類的兩種方法

假設Base為基類

class Base(object):

def __init__(self):

print “Base init”

2.1 普通方法(調用父類的未綁定的構造方法)

在調用一個對象的方法時,該方法的self參數會被自動綁定到對象上(稱為綁定方法)。但如果直接調用類的方法(比如A.__init),那么就沒有實例會被綁定。這樣就可以自由的提供需要的self參數,這種方法稱為未綁定方法。

class Leaf(Base):

def __init__(self):

Base.__init__(self)

print ("Leaf init")

2.2 super方法

class Leaf(Base):

def __init__(self):

super(Leaf, self).__init__() # 在單繼承中等價于super().__init__()

print “Leaf init”

2.3 上述兩個方法的結果

>>>leaf = Leaf()

"Base init"

"Leaf init"

在Python3中的類都是新式類,廣度優先的查找順序,在定義一個類時就會生成一個MRO列表(經典類沒有MRO列表,深度優先),查找順序就是按照這個列表中的類的順序從左到右進行的。

3、鉆石繼承中的問題

”鉆石繼承“指的是一個子類繼承自多個父類,成鉆石形狀。

3.1 如何解決鉆石繼承中父類被多次初始化

C++使用虛擬繼承來解決鉆石繼承問題;Java禁止使用多繼承;Ruby禁止使用多繼承;Python和C++一樣,支持多繼承的語法。但Python的解決思路和C++完全不一樣,Python是的用就是super。所以,我們有必要來詳細探討super的機制。

我把第二章的代碼用super重寫一下,使用如下的繼承關系

class Base(object):

def __init__(self):

print ("Base init")

class Medium1(Base):

def __init__(self):

super(Medium1, self).__init__()

print ("Medium1 init")

class Medium2(Base):

def __init__(self):

super(Medium2, self).__init__()

print ("Medium2 init")

class Leaf(Medium1, Medium2):

def __init__(self):

super(Leaf, self).__init__()

print ("Leaf init")

>>> leaf = Leaf()

"Base init"

"Medium2 init"

"Medium1 init"

"Leaf init"

可以看到整個初始化過程符合我們的預期,Base只被初始化了1次。而且重要的是,相比原來的普通寫法,super方法并沒有寫額外的代碼,也沒有引入額外的概念.

3.2 super的內核:MRO

要理解super的原理,就要先了解mro。mro是method resolution order的縮寫,表示了類繼承體系中的成員解析順序。

在python中,每個類都有一個mro的類方法。我們來看一下鉆石繼承中,Leaf類的mro是什么樣子的:

>>>Leaf.mro()

[Leaf, Medium1, Medium2, Base]

可以看到mro方法返回的是一個祖先類的列表。Leaf的每個祖先都在其中出現一次,這也是super在父類中查找成員的順序。

通過mro,python巧妙地將多繼承的圖結構,轉變為list的順序結構。super在繼承體系中向上的查找過程,變成了在mro中向右的線性查找過程,任何類都只會被處理一次。

通過這個方法,python解決了多繼承中的2大難題:

查找順序問題。從Leaf的mro順序可以看出,如果Leaf類通過super來訪問父類成員,那么Medium1的成員會在Medium2之前被首先訪問到。如果Medium1和Medium2都沒有找到,最后再到Base中查找。

鉆石繼承的多次初始化問題。在mro的list中,Base類只出現了一次。事實上任何類都只會在mro list中出現一次。這就確保了super向上調用的過程中,任何祖先類的方法都只會被執行一次。

至于mro的生成算法,可以參考這篇wiki:C3算法

3.3 super的具體用法

首先看一下super的官方文檔,重點講第一種和第三種的用法,因為第二種用處不大

Help on class super in module __builtin__:

class super(object)

| super(type, obj) -> bound super object; requires isinstance(obj, type)

| super(type) -> unbound super object

| super(type, type2) -> bound super object; requires issubclass(type2, type)

3.2.1 super(type,obj)

這種寫法要從右往左的分析參數:obj告訴我們self綁定的對象所屬類的MRO順序,type告訴我們從MRO順序的哪個位置開始找

當我們在Leaf的init中這樣寫super時,super(Leaf, self).init()的意思是說:

獲取self所屬類的mro, 也就是[Leaf, Medium1, Medium2, Base]

從mro中Leaf右邊的一個類開始,依次尋找__init__函數。這里是從Medium1開始尋找

一旦找到,就把找到的__init__函數綁定到self對象,并返回

class Leaf(Medium1, Medium2):

def __init__(self):

super(Leaf, self).__init__()

print “Leaf init”

從這個執行流程可以看到,如果我們不想調用Medium1的__init__,而想要調用Medium2的__init__,那么super應該寫成:super(Medium1, self).__ init __()

3.2.2 super(type,type2)

當我們在Leaf中寫類方法的super時:

class Leaf(Medium1, Medium2):

def __new__(cls):

obj = super(Leaf, cls).__new__(cls)

print “Leaf new”

return obj

super(Leaf, cls).new(cls)的意思是說:

獲取cls這個類的mro,這里也是[Leaf, Medium1, Medium2, Base]

從mro中Leaf右邊的一個類開始,依次尋找__new__函數

一旦找到,就返回“非綁定”的__new__函數

3.2.3 super一些補充的知識點

super實現原理:通過c3算法,生成mro(method resolution order)列表,根據列表中元素順序查詢調用。新式類調用順序為廣度優先,舊式類為深度優先,可以通過__mro__來查看。

python2沒有默認繼承object;python3默認全部繼承自object類,都是新式類

如果子類繼承了多個父類,它只需要使用一次super函數就可以

4. 子類如何訪問父類的同名方法

講了這么多,把上面的知識點綜合起來,我們就可以解決子類如何訪問父類的同名方法。

看下面的代碼:

class A:

def f_a(self):

print('--------A--------')

class B:

def f_a(self):

print('-------B-------')

class C(A,B):

def f_a(self):

print('--------C--------')

c = C()

c.f_a()

》》》--------C--------

如果我們想在C類中的f_a方法里面使用父類A或者父類B的方法該如何操作呢

方法有兩種:

4.1 方法一:調用父類的未綁定方法

class C(A,B):

def f_a(self):

A.f_a(self)

B.f_a(self)

print('--------C--------')

c = C()

c.f_a()

》》》--------A--------

》》》-------B-------

》》》--------C--------

這里調用父類的f_a方法時括號里面要寫self,表明這是一個類調用。

缺點:比如說如果修改了父類的名稱,那么在子類中會涉及多出修改,并且python是允許多繼承的語言,上述方法在多繼承時就要重復寫多次,顯得累贅,為了解決這些問題,python引進了super()機制。

4.2 super機制

class C(A,B):

def f_a(self):

super().f_a()

print('--------C--------')

c = C()

c.f_a()

》》》--------A--------

》》》--------C--------

這里直接使用super()方法會調用A類的f_a方法,因為它會默認多繼承中從左到右的順序來調用,那么有人就會問了,假如我想調用B類中的f_a方法是不是把A和B對調下呢,這種方法也行,不過這不算的上是一種較為巧妙的方法。

我們還可以使用super()方法,但要對其修改下:

class C(A,B):

def f_a(self):

super(C,self).f_a()

super(A,self).f_a()

print('--------C--------')

c = C()

c.f_a()

》》》--------A--------

》》》-------B-------

》》》--------C--------

super(C,self).f_a()會調用最左邊的(即A類)的f_a方法,而super(A,self).f_a()會調用A類后面那個類的f_a()方法,若果繼承的不止兩個類,如果要調用某個類方法,只要知道前一個類名就可以調用。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/258621.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/258621.shtml
英文地址,請注明出處:http://en.pswp.cn/news/258621.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android-Universal-Image-Loader 的使用說明

這個圖片異步載入并緩存的類已經被非常多開發人員所使用,是最經常使用的幾個開源庫之中的一個,主流的應用,隨便反編譯幾個火的項目,都能夠見到它的身影。但是有的人并不知道怎樣去使用這庫怎樣進行配置,網上查到的信息…

faster rcnn end2end 訓練與測試

除了前面講過的rpn與fast rcnn交替訓練外,faster rcnn還提供了一種近乎聯合的訓練,姑且稱為end2end訓練。 根據論文所講,end2end的訓練一氣呵成,對于前向傳播,rpn可以作為預設的網絡提供proposal.而在后向傳播中&…

jquery ui動態切換主題的一種實現方式

這兩天看coreservlets上的jQuery教程&#xff0c;雖然比較老了&#xff0c;不過講得還是不錯。最后一部分講jQuery ui 主題切換&#xff0c;用他介紹的方法實現不了。于是自己修改了下&#xff0c;可以了。代碼如下&#xff1a;html部分&#xff1a;<fieldset class"ui…

[學習總結]7、Android AsyncTask完全解析,帶你從源碼的角度徹底理解

我們都知道&#xff0c;Android UI是線程不安全的&#xff0c;如果想要在子線程里進行UI操作&#xff0c;就需要借助Android的異步消息處理機制。之前我也寫過了一篇文章從源碼層面分析了Android的異步消息處理機制&#xff0c;感興趣的朋友可以參考 Android Handler、Message完…

python字頻統計軟件_python結巴分詞以及詞頻統計實例

python結巴分詞以及詞頻統計實例發布時間&#xff1a;2018-03-20 14:52,瀏覽次數&#xff1a;773, 標簽&#xff1a;python# codingutf-8Created on 2018年3月19日author: chenkai結巴分詞支持三種分詞模式&#xff1a;精確模式: 試圖將句子最精確地切開&#xff0c;適合文…

html從入門到賣電腦(三)

CSS3中和動畫有關的屬性有三個 transform、 transition 和 animation。下面來一一說明: transform 從字面來看transform的釋義為改變&#xff0c;使…變形&#xff1b;轉換 。這里我們就可以理解為變形。那都能怎么變呢&#xff1f; none 表示不進行變換&#xff1b; rotat…

visual studio 2015安裝 無法啟動程序,因為計算機丟失D3DCOMPILER_47.dll 的解決方法

對于題目中的解決方法&#xff0c;我查到了微軟提供的一個方案&#xff1a;https://support.microsoft.com/en-us/help/4019990/update-for-the-d3dcompiler-47-dll-component-on-windows 進入如下頁面&#xff1a;http://www.catalog.update.microsoft.com/Search.aspx?qKB4…

UI1_UIView層操作

// // ViewController.m // UI1_UIView層操作 // // Created by zhangxueming on 15/7/1. // Copyright (c) 2015年 zhangxueming. All rights reserved. //#import "ViewController.h"interface ViewController ()endimplementation ViewController- (void)view…

JavaScript Patterns 1 Introduction

1.1 Pattern "theme of recurring events or objects… it can be a template or model which can be used to generate things" (http://en.wikipedia.org/wiki/Pattern). ? Design patterns - Elements of Reusable Object-Oriented Software. ? Coding patte…

基于像素聚類的分割方法基于slic的方法_博士論文摘要 | 張榮春:數碼影像與TLS點云數據融合提取地質結構面方法研究...

《測繪學報》構建與學術的橋梁 拉近與權威的距離數碼影像與TLS點云數據融合提取地質結構面方法研究張榮春1,21.南京郵電大學地理與生物信息學院, 江蘇 南京 210023;2.河海大學地球科學與工程學院, 江蘇 南京 211100收稿日期&#xff1a;2019-03-27基金項目&#xff1a;國家自然…

制作IOS 后臺極光推送時,遇到的小問題

推送廣義上分為兩種&#xff0c; 一種是 程序在前臺的時候&#xff0c;不想在任務欄里面顯示通知&#xff0c;直接在app中進行某種操作。這個叫做自定義消息。這個是在前臺時&#xff0c;app與極光后臺建立了一個長鏈接。 另一種是 程序處于前、后臺 或者殺死狀態的時候&…

Visual Studio 2008 環境變量的配置(參考設置VS2010)

本文轉載自&#xff1a;http://blog.csdn.net/tracyliang223/article/details/21539361COPY FROM&#xff1a;http://www.cnblogs.com/waterlin/archive/2011/10/31/2230341.html 在調試 Visual Studio 2008 程序時&#xff0c;經常有一些動態鏈接庫&#xff08;即 dll 文件&am…

Linq 中 Any與All

昨天突然看到之前寫的一個積累文檔&#xff0c;其中文檔中有一個Linq Any和All的注意事項&#xff1a;注意Any 和 All var list new List<int>(); var aa list.All(n > n > 1); var bb list.Any(n > n > 1); // aa: true bb: false其中List是一個元…

jaxb轉xml空值雙標簽_單品運營思維:標簽-詞路-聚焦-直搜-超直

非標品標簽思維&#xff1a;針對非標品 主要是2.0為主的打法根據搜索入池的關鍵詞&#xff0c;有什么詞做什么詞。有個細節&#xff1a;不一定進什么詞做什么詞&#xff0c;這個維度當中加入3.0的思維3.0入手 轉2.0再切3.0(檢測詞路健康度&#xff0c;非嚴格意義估算單量)舉例&…

如何在PFSense中設置故障轉移和負載平衡

故障轉移是一種備份操作模式&#xff0c;僅在主系統由于系統故障或任何計劃停機時間而變得不可用時&#xff0c;系統組件&#xff08;如網絡&#xff09;的操作才由輔助系統承擔。在本教程中&#xff0c;我們將看到如何設置故障轉移和負載平衡&#xff0c;以使pfSense能夠將流量…

圖像金字塔總結

本文轉載自&#xff1a; http://blog.csdn.net/dcrmg/article/details/52561656 一、 圖像金字塔 圖像金字塔是一種以多分辨率來解釋圖像的結構&#xff0c;通過對原始圖像進行多尺度像素采樣的方式&#xff0c;生成N個不同分辨率的圖像。把具有最高級別分辨率的圖像放在底部…

表單的get和post使用情景

GET和POST兩種方法都是將數據送到服務器&#xff0c;但你該用哪一種呢&#xff1f;HTTP標準包含這兩種方法是為了達到不同的目的。POST用于創建資源&#xff0c;資源的內容會被編入HTTP請示的內容中。例如&#xff0c;處理訂貨表單、在數據庫中加入新數據行等。 當請求無副作用…

什么叫做羅列式_項目起盤的時候,如何確定自己該做什么社群?

這是祁杰『社群日記』第48篇持續日更&#xff0c;做最懂社群的營銷咨詢人很多人手上有資源&#xff0c;準備起盤項目的時候&#xff0c;總會思考一個問題&#xff1a;我能做什么樣的社群&#xff1f;今天我們從用戶需求出發&#xff0c;拆解一下哪些社群是能夠確切地滿足用戶的…

C++ exit 與 return 淺析

【摘要】 本文從代碼形式。經常使用方式&#xff0c;相關概念&#xff0c;調用關系和比較分析&#xff0c;這5個維度淺析 exit 與 return 在C的同樣點與差別。【常見形式】 exit(0)&#xff1a; 正常執行程序并退出程序。 exit(1)&#xff1a; 非正常執行導致退出程序&…

Feature Pyramid Networks for Object Detection 總結

最近在閱讀FPN for object detection,看了網上的很多資料&#xff0c;有些認識是有問題的&#xff0c;當然有些很有價值。下面我自己總結了一下&#xff0c;以供參考。 1. FPN解決了什么問題&#xff1f; 答&#xff1a; 在以往的faster rcnn進行目標檢測時&#xff0c;無論…