網站首頁 編程語言 正文
type
type
方法有兩種重載形式:
-
type(o: object)
; type(name: str, bases:Tuple[type, ...], dict:Mapping[str: Any], **kwds)
使用第一種重載形式的時候,傳入一個【object】類型,返回一個【type】對象,通常與object.__class__
方法的返回值相同。
使用第二種重載形式的時候,也會得到一個【type】對象,本質上來說這是一種動態類,參數含義如下:
- name:字符型,指定動態類的類名,也是該動態類的
__name__
屬性; - bases:type類型元祖,指定動態類繼承的父類,也是該動態類的
__bases__
屬性; - dict:字典類型,指定動態類的屬性和方法定義,經過一定的包裝后成為動態類的
__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
成功創造了一個動態類并添加了幾個類屬性,由于指定了【OldClass】作為父類,所以動態生成的類也具有【OldClass】的全部特性。
動態生成一個類的時候不光可以指定類屬性,還可以綁定類方法,示例如下:
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("使用動態綁定的方法??!") print(my_dynamic_cls.__dict__) ----------------------------- 使用動態綁定的方法!! {'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
方法用來檢查給定的對象是否是給定類型的實例或者是給定類型的任意子類的實例,通常使用該方法進行對象類型校驗。
示例
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
總結一下,isinstance
方法檢查的范圍就是參數的模板層按照繼承關系進行檢索。
issubclass
issubclass(class: type, classinfo: Union[type, ...])
方法用來判斷指定的兩個類型之間的從屬關系,如果【class】是【classinfo】的子類返回真(True),否則返回假(False)。
有幾點注意事項這里說一下:
-
issubclass(cls, cls)
返回是真; - 【classinfo】參數可以是一個type元祖,只要有一個條件為真,則表達式結果為真;
- 【class】和【classinfo】必須是元類或者類,不能是一個對象,總結一下就是參數要么是【type】的子類要么是【type】的實例;
示例
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
從程序結果可以看到傳入元類和類返回永遠是假,并且不能直接傳入對象。
綜合示例
為了更好的讓大家明白這三者之間的區別和聯系,我畫了一張圖
這是初始狀態,定義了三個對象,三個類和三個元類,它們之間的關系如上圖所示;
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
針對對象
以【O2】為例,它的檢索范圍如下圖紅線所示:
針對類
以【C3】為例,它的檢索范圍如下圖紅線所示:
issubclass
針對類
以【C2】為例,返回真值的范圍如下:
針對元類
以【M2】為例,返回真值的范圍如下:
總結
調用type
方法
- 如果是對象,則會順著實例化的逆方向尋找,也就是找到創建它的類;
- 如果是類,則會順著繼承逆方向尋找,直到找到它的元類。
調用isinstance
方法
- 如果是對象,那么實例化它的類和該類的所有父類都返回真,也就是沿著繼承路徑上都是返回真,但 不能是元類;
- 如果是類,那么就找其元類的繼承路徑,路徑上所有的元類都返回真。
調用issubclass
方法
- 參數必須是同一個類型,元類或者類;
- 按照繼承路徑進行判斷。
原文鏈接:https://juejin.cn/post/7193577879345561657
相關推薦
- 2022-10-31 利用WinForm實現上左右布局的方法詳解_C#教程
- 2023-07-25 使用線程池異步執行定時任務
- 2024-03-17 基于linux使用Centos7實現Samba服務器安裝和配置(超詳細)
- 2023-11-15 linux查看目錄的大小,指定目錄查看所占的空間大小
- 2022-05-05 C#?模式匹配完全指南_C#教程
- 2022-07-22 Idea操作普通項目變為maven項目
- 2022-12-06 Docker基礎和常用命令詳解_docker
- 2022-03-29 C語言中的盜賊(小偷)問題詳解_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支