詳解Python是如何實現issubclass的

2022-10-03 22:00:32 字數 2766 閱讀 2054

使用python內建的issubclass方法很方便的檢測乙個類是否是另乙個類程式設計客棧的子類。

這個是issubclass的文件:

issubclass(class, classinfo)

return true if class is a subclass (direct, indirect or virtual) of classinfo. a class is considered a subclass of itself. classinfo may be a tuple of class objects, in which case every entry in classinfo will be checked. in any other case, a typeerror exception is raised.

乙個類的子類可以是直接的、間接的、或者是虛擬的。

issubclass的第二個引數classinfo可以是乙個類物件或者包含類物件的tuple(只要其中乙個檢測成功即返回true)。

一些使用示例:

>>> class a(object):

... pass

...>>> class b(a):

... pass

...>>> class c(b, a):

... pass

...>>> class d(c):

... pass

...>>> issubclass(d, d), issubclass(d, c), issubclass(d, b), issubclass(d, a), issubclass(d, object)

(true, true, true, true, true)

>>> d.__bases__

(,)>>> d.__mro__

(, , , , )

d是d的子類,d定義時的基類是c,所以d是c的子類,而且d是b,a,object的間接子類。

__mro__是類屬性, 在類定義完畢python解析器便通過一種c3演算法將所有的父類以method resolution order的順序儲存到乙個元組裡, 成為類的屬性。

所以issubclass可以這樣簡單的實現:

def issubclass(cls, classinfo):

if classinfo in cls.__mro__:

return true

程式設計客棧 return false

python的issubclass是內建函式(一般是c實現),實際上要複雜很多,要檢測引數型別,如第乙個引數必須是type型別,第二個引數是type型別或者tuple型別。還要考慮該類是否是虛擬的子類,以及子類的子類。

例如:>>> from collections import abc

>>> class e:

... def __len__(self):

... return 1

...>>> issubclass(e, abc.sized)

true

>>> e.__mro__

(, )

>>> class f:

... pass

...>>> issubclass(f, abc.sized)

false

>>> abc.sized.register(f)

>>> issubclass(f, abc.sized)

true

python是動態型別語言,長久以來使用duck type(鴨子型別)形式程式設計,不管物件是什麼型別,只要實現了所需要的方法。

現在有了abcs, 可以用於判斷某個類或者某個物件是不是abcs的子類或者例項,但這個類並不需要顯示的繼承於abcs, 因為python內建的abcs有一種註冊機制可將乙個類註冊為它的子類。如上例子的register方法。

還有一種機制是可以定製乙個__subclasshook__方法,將某種型別的類認定為子類。

如abc.sized的__subclasshook__是這樣子的:

@classmethod

def __subclasshook__(cls, c程式設計客棧):

if cls is sized:

if any("__len__" in b.__dict__ for b in c.__mro__):

return true

return notimplemented

所以有__len__方法的e類是abc.sized的子類, 這個__subclasshook__方法是通過__subclasscheck__方法呼叫的,這個__subclasscheck__是每乙個abc類都有的方法,在abcmeta類(其他abc類都繼承於它)實現。

現在的issubclass函式的實現,會先判斷classinfo是否有__subclasscheck__方法,如果有此方法,則判斷子類的邏輯由該方法返回,即覆蓋issubclass的實現(cpython)。

__subclasscheck__會分幾個步驟進行判斷:

具體原始碼在:

相關的cpython實現在:

而基本上isinstance(object, classinfo)方法的實現只需要呼叫issubclass(type(object), classinfo)

參考:29.7. abc — abstract base classes :

pep 3119 – introducing abstract base classes:

本文標題: 詳解python是如何實現issubclass的

本文位址: /jiaoben/python/266619.html

Python如何實現轉換URL詳解

設計乙個演算法,將url轉換成5部分,分別是 schema netloc path query params fragment。問題url的中文名叫統一資源定位符,就是咱們常說的 設計乙個演算法,將url轉換成5部分,分別是 schema netl程式設計客棧oc path query params...

詳解redis是如何實現佇列訊息的ack

前言 由於公司提供的佇列實在太過於蛋疼而且還限制不能使用其他佇列,但為了保證資料安全性需要乙個可以有ack功能的佇列。原生的redis中通過l r push pop方式來實現佇列的功能,這個當然是沒辦法滿足需求的 沒有ack功能 所以需要自己對redis的list 佇列 做個小小的調整。大體思路為在...

python如何實現繼承 python如何實現繼承

物件導向程式設計的乙個主要優點是重用。繼承是實現同樣的機制之一。在繼承中,類 通常稱為超類 由另乙個類 通常稱為子類 繼承。子類為超類新增了一些屬性。下面是乙個示例python程式,用於說明如何在python中實現繼承。a python program to demonstrate inherita...