一文帶你了解Python中的type,isinstance和issubclass
type
type方法有兩種重載形式:
type(o: object);type(name: str, bases:Tuple[type, ...], dict:Mapping[str: Any], **kwds)
使用第一種重載形式的時(shí)候,傳入一個(gè)【object】類型,返回一個(gè)【type】對(duì)象,通常與object.__class__方法的返回值相同。
使用第二種重載形式的時(shí)候,也會(huì)得到一個(gè)【type】對(duì)象,本質(zhì)上來說這是一種動(dòng)態(tài)類,參數(shù)含義如下:
- name:字符型,指定動(dòng)態(tài)類的類名,也是該動(dòng)態(tài)類的
__name__屬性; - bases:type類型元祖,指定動(dòng)態(tài)類繼承的父類,也是該動(dòng)態(tài)類的
__bases__屬性; - dict:字典類型,指定動(dòng)態(tài)類的屬性和方法定義,經(jīng)過一定的包裝后成為動(dòng)態(tài)類的
__dict__屬性;
示例
重載形式1
class A(object):
pass
?
a = A()
print(type(a), a.__class__, type(A))
-----------------------------
<class '__main__.A'> <class '__main__.A'> <class 'type'>
重載形式2
class OldClass(object):
a = 1
?
def __init__(self) -> None:
self.name = "OldClass"
?
def get_name(self):
return self.name
?
?
my_dynamic_cls = type('DynamicClass', (OldClass,),
dict(name='dynamic', a=2, b=3, c=4))
?
new_obj = my_dynamic_cls()
print(my_dynamic_cls.__dict__)
print(new_obj.__dict__, type(new_obj))
-----------------------------
{'name': 'dynamic', 'a': 2, 'b': 3, 'c': 4, '__module__': '__main__', '__doc__': None}
{'name': 'OldClass'} <class '__main__.DynamicClass'>
在上面的示例中我們使用type成功創(chuàng)造了一個(gè)動(dòng)態(tài)類并添加了幾個(gè)類屬性,由于指定了【OldClass】作為父類,所以動(dòng)態(tài)生成的類也具有【OldClass】的全部特性。
動(dòng)態(tài)生成一個(gè)類的時(shí)候不光可以指定類屬性,還可以綁定類方法,示例如下:
class OldClass(object):
a = 1
?
def __init__(self) -> None:
self.name = "OldClass"
?
def get_name(self):
return self.name
?
def print_msg(msg: str) -> None:
print(msg)
?
my_dynamic_cls = type('DynamicClass ', (OldClass,),
dict(name='dynamic', a=2, b=3, c=4, method=print_msg))
?
new_obj = my_dynamic_cls()
my_dynamic_cls.method("使用動(dòng)態(tài)綁定的方法?。?)
print(my_dynamic_cls.__dict__)
-----------------------------
使用動(dòng)態(tài)綁定的方法??!
{'name': 'dynamic', 'a': 2, 'b': 3, 'c': 4, 'method': <function print_msg at 0x00000188189F73A0>, '__module__': '__main__', '__doc__': None}
isinstance
Return True if the object argument is an instance of the classinfo argument, or of a (direct, indirect, or virtual) subclass thereof. If object is not an object of the given type, the function always returns False. If classinfo is a tuple of type objects (or recursively, other such tuples) or a union of multiple types, return True if object is an instance of any of the types. If classinfo is not a type or tuple of types and such tuples, a TypeError exception is raised. TypeError may not be raised for an invalid type if an earlier check succeeds.
——PythonDoc
isinstance方法用來檢查給定的對(duì)象是否是給定類型的實(shí)例或者是給定類型的任意子類的實(shí)例,通常使用該方法進(jìn)行對(duì)象類型校驗(yàn)。
示例
class AMetaClass(type):
?
def __new__(cls, *args, **kwargs):
return type.__new__(cls, *args, **kwargs)
?
?
class BMetaClass(AMetaClass):
pass
?
?
class AClass(object, metaclass=BMetaClass):
?
def __init__(self, name: str) -> None:
self.name = name
?
?
class BClass(AClass):
?
def __init__(self, name: str) -> None:
super().__init__(name)
obj_a = AClass('a')
obj_b = BClass('b')
-----------------------------
print(isinstance(obj_b, AClass)) -> True
print(isinstance(obj_b, BClass)) -> True
print(isinstance(obj_b, AMetaClass)) -> False
print(isinstance(obj_b, BMetaClass)) -> False
print(isinstance(obj_b, type)) -> False
print(isinstance(BClass, AMetaClass)) -> True
print(isinstance(BClass, BMetaClass)) -> True
print(isinstance(BClass, type)) -> True
總結(jié)一下,isinstance方法檢查的范圍就是參數(shù)的模板層按照繼承關(guān)系進(jìn)行檢索。
issubclass
issubclass(class: type, classinfo: Union[type, ...])方法用來判斷指定的兩個(gè)類型之間的從屬關(guān)系,如果【class】是【classinfo】的子類返回真(True),否則返回假(False)。
有幾點(diǎn)注意事項(xiàng)這里說一下:
issubclass(cls, cls)返回是真;- 【classinfo】參數(shù)可以是一個(gè)type元祖,只要有一個(gè)條件為真,則表達(dá)式結(jié)果為真;
- 【class】和【classinfo】必須是元類或者類,不能是一個(gè)對(duì)象,總結(jié)一下就是參數(shù)要么是【type】的子類要么是【type】的實(shí)例;
示例
class AMetaClass(type):
?
def __new__(cls, *args, **kwargs):
return type.__new__(cls, *args, **kwargs)
?
?
class BMetaClass(AMetaClass):
pass
?
?
class AClass(object, metaclass=BMetaClass):
?
def __init__(self, name: str) -> None:
self.name = name
?
?
class BClass(AClass):
?
def __init__(self, name: str) -> None:
super().__init__(name)
obj_a = AClass('a')
obj_b = BClass('b')
-----------------------------
?
issubclass(AMetaClass, type) -> True
issubclass(BMetaClass, type) -> True
issubclass(BMetaClass, AMetaClass) -> True
issubclass(AClass, AMetaClass) -> False
issubclass(AClass, BMetaClass) -> False
issubclass(BClass, AClass) -> True
issubclass(AClass, obj_a) -> TypeError: arg 2 must be a class
issubclass(obj_a, AClass) -> TypeError: arg 1 must be a class
從程序結(jié)果可以看到傳入元類和類返回永遠(yuǎn)是假,并且不能直接傳入對(duì)象。
綜合示例
為了更好的讓大家明白這三者之間的區(qū)別和聯(lián)系,我畫了一張圖

這是初始狀態(tài),定義了三個(gè)對(duì)象,三個(gè)類和三個(gè)元類,它們之間的關(guān)系如上圖所示;
class M1(type):
?
def __new__(cls, *args, **kwargs):
return type.__new__(cls, *args, **kwargs)
?
?
class M2(M1):
pass
?
?
class M3(type):
?
def __new__(cls, *args, **kwargs):
return type.__new__(cls, *args, **kwargs)
?
?
class C1(metaclass=M3):
pass
?
?
class C2(C1):
pass
?
?
class C3(metaclass=M2):
pass
?
?
o1 = C1()
o2 = C2()
o3 = C3()isinstance
針對(duì)對(duì)象
以【O2】為例,它的檢索范圍如下圖紅線所示:

針對(duì)類
以【C3】為例,它的檢索范圍如下圖紅線所示:

issubclass
針對(duì)類
以【C2】為例,返回真值的范圍如下:

針對(duì)元類
以【M2】為例,返回真值的范圍如下:

總結(jié)
調(diào)用type方法
- 如果是對(duì)象,則會(huì)順著實(shí)例化的逆方向?qū)ふ?,也就是找到?chuàng)建它的類;
- 如果是類,則會(huì)順著繼承逆方向?qū)ふ?,直到找到它的元類?/li>
調(diào)用isinstance方法
- 如果是對(duì)象,那么實(shí)例化它的類和該類的所有父類都返回真,也就是沿著繼承路徑上都是返回真,但 不能是元類;
- 如果是類,那么就找其元類的繼承路徑,路徑上所有的元類都返回真。
調(diào)用issubclass方法
- 參數(shù)必須是同一個(gè)類型,元類或者類;
- 按照繼承路徑進(jìn)行判斷。
以上就是一文帶你了解Python中的type,isinstance和issubclass的詳細(xì)內(nèi)容,更多關(guān)于Python type isinstance issubclass的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python通過TensorFLow進(jìn)行線性模型訓(xùn)練原理與實(shí)現(xiàn)方法詳解
這篇文章主要介紹了Python通過TensorFLow進(jìn)行線性模型訓(xùn)練原理與實(shí)現(xiàn)方法,結(jié)合實(shí)例形式詳細(xì)分析了Python通過TensorFLow進(jìn)行線性模型訓(xùn)練相關(guān)概念、算法設(shè)計(jì)與訓(xùn)練操作技巧,需要的朋友可以參考下2020-01-01
解決python3.5 正常安裝 卻不能直接使用Tkinter包的問題
今天小編就為大家分享一篇解決python3.5 正常安裝 卻不能直接使用Tkinter包的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-02-02
python函數(shù)遞歸調(diào)用的實(shí)現(xiàn)
本文主要介紹了python函數(shù)遞歸調(diào)用的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
Python實(shí)現(xiàn)生成指定大小文件的示例詳解
這篇文章主要為大家詳細(xì)介紹了Python如何實(shí)現(xiàn)生成指定大小文件,例如txt/圖片/視頻/csv等,文中的示例代碼講解詳細(xì),需要的可以參考下2023-08-08

