Python多繼承解析順序的C3線性演算法流程解析

来源:https://www.cnblogs.com/PyKK2019/archive/2019/04/30/10798227.html
-Advertisement-
Play Games

Python多繼承MRO 在Python2.1中,採用了經典類,使用深度優先演算法解析。 Python2.2中,引入了新式類,使用深度優先演算法和廣度優先演算法。 在Python2.3以後的版本中,經典類和新式類共存,使用了DFS演算法和C3演算法。 Python2中的經典類 Python3的新式類 C3演算法 ...


Python多繼承MRO

在Python2.1中,採用了經典類,使用深度優先演算法解析。
Python2.2中,引入了新式類,使用深度優先演算法和廣度優先演算法。
在Python2.3以後的版本中,經典類和新式類共存,使用了DFS演算法和C3演算法。
Python2中的經典類

class A(object):
    pass

Python3的新式類

class A:
    pass

C3演算法

In computing, the C3 superclass linearization is an algorithm used primarily to obtain the order in which methods should be inherited (the "linearization") in the presence of multiple inheritance, and is often termed Method Resolution Order (MRO).
這是維基百科中的定義,下麵這張圖是一張多繼承的關係圖:
在這裡插入圖片描述

那麼這裡的mro解析順序是如何的呢?單純看圖很難得出答案。
C3線性演算法的推導過程如下:
假設類C繼承自父類B1,...Bn,類C的解析列表公式如下:
在這裡插入圖片描述
這個公式表明C的解析列表是通過對其所有父類的解析列表及其父類一起merge得到的。
merge操作分為如下幾個步驟:

  1. 選取merge中的第一個列表記為當前列表K
  2. h = head(K), 如果h沒有出現在其他任何列表的tail列表中除了第一個元素,其餘的稱之為tail)當中,那麼將其加入類C的線性化列表中,並將其從merge中的所有列表移除,之後重覆步驟2.
  3. 否則,設置Kmerge的下一個列表,重覆2中的操作
  4. 如果merge的所有類都被移除,則輸出類創建成功;如果不能找到下一個h,則輸出C類拋出異常。

推導過程

我們用上面的那張圖試一下推導出mro的解析順序。
上面那張圖轉換為python代碼如下:
轉換成Python代碼

O = object
class A(O): pass

class B(O): pass

class C(O): pass

class D(O): pass

class E(O): pass

class K1(A, B, C): pass

class K2(D, B, E): pass

class K3(D, A): pass

class Z(K1, K2, K3): pass

print(Z.mro())

推導

L(K1) = K1 + merge(L[A],L[B],L[C],(A,B,C))
      = K1 + merge(L[A,O],L[B,O],L[C,O],(A,B,C))
      = [K1,A] + merge(L[O],L[B,O],L[C,O],(B,C))
      = [K1,A,B] + merge(L[O],L[O],L[C,O],(C))
      = [K1,A,B,C] + merge(L[O],L[O],L[O])
      = [K1,A,B,C,O]

L(K2) = [K2,D,B,E,O]
L(K3) = [K3,D,A,O]

以上是K1,K2,K3的解析順序

下麵是Z的推導過程

L(Z) = Z + merge(L(K1)+L(K2)+L[K3],(K1,K2,K3))
     = Z + merge(L[K1,A,B,C,O]+L(K2,D,B,E,O)+L(K3,D,A,O),(K1,K2,K3))
     = [Z,K1] + merge(L[A,B,C,O]+L(K2,D,B,E,O)+L(K3,D,A,O),(K2,K3))
     = [Z,K1,K2] + merge(L[A,B,C,O]+L(D,B,E,O)+L(K3,D,A,O),(K3))
     = [Z,K1,K2,K3] + merge(L[A,B,C,O]+L(D,B,E,O)+L(D,A,O))
     = [Z,K1,K2,K3,D] + merge(L[A,B,C,O]+L(B,E,O)+L(A,O))
     = [Z,K1,K2,K3,D,A] + merge(L[B,C,O]+L(B,E,O)+L(O))
     = [Z,K1,K2,K3,D,A,B] + merge(L[C,O]+L(E,O)+L(O))
     = [Z,K1,K2,K3,D,A,B,C] + merge(L[O]+L(E,O)+L(O))
     = [Z,K1,K2,K3,D,A,B,C,E,O]

我們得出的最終答案為:Z的解析順序:Z->K1->K2->K3->D->A->B->C->E->O
為了驗證答案,我們在python中運行

print(Z.mro())

結果如下

[<class '__main__.Z'>, <class '__main__.K1'>, <class '__main__.K2'>, <class '__main__.K3'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.E'>, <class 'object'>]

和我們推導的結果相同,這就是C3演算法的流程。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 整數反轉 題目描述 給出一個 32 位的有符號整數,你需要將這個整數中每位上的數字進行反轉。 示例 1: 輸入: 123 輸出: 321 示例 2: 輸入: -123 輸出: -321 示例 3: 輸入: 120 輸出: 21 註意: 假設我們的環境只能存儲得下 32 位的有符號整數,則其數值範圍為 ...
  • 使用keytool工具產生帶根CA和二級CA的用戶證書 1 生成根CA 1.1 生成根CA證書 根CA實際是一張自簽CA,自簽CA的使用者和頒發者都是它自己。使用下麵的命令生成根證書,如果沒有指定 則會使用預設在用戶Home目錄下的 秘鑰庫(如果沒有則會創建),輸入秘鑰庫的密碼,填寫根證書的信息,最 ...
  • Python基礎之變數進階,包括了 變數的引用,可變類型和不可變類型,哈希;其中,變數的引用 包括 函數引用的概念,函數引用理解,函數傳參與引用的關係,函數返回值與引用;可變類型和不可變類型 包括 可變類型修改和重賦值對引用的影響;哈希 僅包含 哈希演算法 等 ...
  • 在上一章的指南中,我們寫了一個命名隊列:生產者往該命名隊列發送消息、消費從從該命名隊列中消費消息。在本章中,我們將創建一個工作隊列,用於在多個工作者之間分配耗時的任務。工作隊列(即任務隊列)的主要思想是避免立即執行那些需要等他們執行完成的資源密集型任務。相反,我們將任務安排在稍後完成。我們將任務封裝 ...
  • 在Java運行時的幾個數據區域中,程式計數器,虛擬機棧,本地方法棧3個區域隨著線程而生,隨線程而滅,因此這幾個區域的記憶體分配和回收具有確定性,不需要過多考慮垃圾回收問題,因為方法結束或者線程結束時,記憶體就回收了。但是方法區和堆區不一樣,一個介面或者實現類所需要的記憶體可能不一樣,一個方法的多個分支需要 ...
  • 本文分享了一下我對API的理解以及百度地圖API的使用舉例。 ...
  • 補充上期str尾碼小魔法: .swapcase() 將字元串大小寫互轉,小變大,大變小 .isnumeric() 判斷是否為數字,支持漢字,範圍廣 .isprinttable() 檢測變數中是否有無法顯示的字元,如\n\t存在則返回False .isspace() 判斷是否全部為空格,\t\n也可以 ...
  • 1. 查看Linux 版本 2. 安裝selemium 2.1 通過pip 安裝selenium,先安裝pip: 2.2 如果提示pip更新則執行如下命令: 2.3 pip安裝selenium 2.4 卸載Centos自帶的Mozilla firefox 2.5 下載、解壓firefox 2.6 創 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...