使用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...