小編給大家分享一下使用Python實(shí)現(xiàn)issubclass的方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
成都創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的博州網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!使用Python內(nèi)置的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的第二個參數(shù)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__ (<class '__main__.C'>,) >>> D.__mro__ (<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
D是D的子類,D定義時的基類是C,所以D是C的子類,而且D是B,A,object的間接子類。
__mro__是類屬性, 在類定義完畢Python解析器便通過一種C3算法將所有的父類以method resolution order的順序保存到一個元組里, 成為類的屬性。
所以issubclass可以這樣簡單的實(shí)現(xiàn):
def issubclass(cls, classinfo): if classinfo in cls.__mro__: return True return False
Python的issubclass是內(nèi)置函數(shù)(一般是C實(shí)現(xiàn)),實(shí)際上要復(fù)雜很多,要檢測參數(shù)類型,如第一個參數(shù)必須是type類型,第二個參數(shù)是type類型或者tuple類型。還要考慮該類是否是虛擬的子類,以及子類的子類。
例如:
>>> from collections import abc >>> class E: ... def __len__(self): ... return 1 ... >>> issubclass(E, abc.Sized) True >>> E.__mro__ (<class '__main__.E'>, <class 'object'>) >>> class F: ... pass ... >>> issubclass(F, abc.Sized) False >>> abc.Sized.register(F) <class '__main__.F'> >>> issubclass(F, abc.Sized) True
Python是動態(tài)類型語言,長久以來使用Duck type(鴨子類型)形式編程,不管對象是什么類型,只要實(shí)現(xiàn)了所需要的方法。
現(xiàn)在有了ABCs, 可以用于判斷某個類或者某個對象是不是ABCs的子類或者實(shí)例,但這個類并不需要顯示的繼承于ABCs, 因?yàn)閜ython內(nèi)置的ABCs有一種注冊機(jī)制可將一個類注冊為它的子類。如上例子的register方法。
還有一種機(jī)制是可以定制一個__subclasshook__方法,將某種類型的類認(rèn)定為子類。
如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__方法調(diào)用的,這個__subclasscheck__是每一個ABC類都有的方法,在ABCMeta類(其他ABC類都繼承于它)實(shí)現(xiàn)。
現(xiàn)在的issubclass函數(shù)的實(shí)現(xiàn),會先判斷classinfo是否有__subclasscheck__方法,如果有此方法,則判斷子類的邏輯由該方法返回,即覆蓋issubclass的實(shí)現(xiàn)(CPython)。
__subclasscheck__會分幾個步驟進(jìn)行判斷:
調(diào)用__subclasshook__方法,如果有方法定義
檢查自己是否在待檢測類的__mro__列表里
遞歸檢查待檢測類是否是在注冊子類(內(nèi)置_abc_registry列表屬性)
遞歸檢查待檢測類是否是自己子類的子類
具體源碼在: https://github.com/python/cpython/blob/3.6/Lib/abc.py#L194-L231
相關(guān)的CPython實(shí)現(xiàn)在: https://github.com/python/cpython/blob/0ccc0f6c7495be9043300e22d8f38e6d65e8884f/Objects/abstract.c#L2223
而基本上isinstance(object, classinfo)方法的實(shí)現(xiàn)只需要調(diào)用issubclass(type(object), classinfo)
以上是“使用Python實(shí)現(xiàn)issubclass的方法”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
分享標(biāo)題:使用Python實(shí)現(xiàn)issubclass的方法-創(chuàng)新互聯(lián)
文章源于:http://vcdvsql.cn/article14/ddhege.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、App開發(fā)、微信公眾號、服務(wù)器托管、網(wǎng)站導(dǎo)航、面包屑導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容