一文带你了解Python中的type,isinstance和issubclass

 更新时间:2023年01月29日 08:16:13   作者:勇敢努力拼搏  
这篇文章主要为大家详细介绍了Python中的type、isinstance和issubclass的使用,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下

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方法

  • 参数必须是同一个类型,元类或者类;
  • 按照继承路径进行判断。

以上就是一文带你了解Python中的type,isinstance和issubclass的详细内容,更多关于Python type isinstance issubclass的资料请关注脚本之家其它相关文章!

相关文章

  • Python通过TensorFLow进行线性模型训练原理与实现方法详解

    Python通过TensorFLow进行线性模型训练原理与实现方法详解

    这篇文章主要介绍了Python通过TensorFLow进行线性模型训练原理与实现方法,结合实例形式详细分析了Python通过TensorFLow进行线性模型训练相关概念、算法设计与训练操作技巧,需要的朋友可以参考下
    2020-01-01
  • 利用Python破解摩斯密码

    利用Python破解摩斯密码

    摩尔斯电码( 又译为摩斯密码,英语:Morse code)是一种时通时断的信号代码,通过不同的排列顺序来表达不同的英文字母、数字和标点符号。本文将通过Python代码来实现破解摩斯密码,感兴趣的可以学习一下
    2022-02-02
  • 解决python3.5 正常安装 却不能直接使用Tkinter包的问题

    解决python3.5 正常安装 却不能直接使用Tkinter包的问题

    今天小编就为大家分享一篇解决python3.5 正常安装 却不能直接使用Tkinter包的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-02-02
  • python函数递归调用的实现

    python函数递归调用的实现

    本文主要介绍了python函数递归调用的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • python的rllib库你了解吗

    python的rllib库你了解吗

    这篇文章主要介绍了python urllib库的使用,帮助大家更好的利用python学习爬虫,感兴趣的朋友可以了解下,希望能够给你带来帮助
    2021-11-11
  • 用Python生成HTML表格的方法示例

    用Python生成HTML表格的方法示例

    这篇文章主要介绍了用Python生成HTML表格的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • Python实现生成指定大小文件的示例详解

    Python实现生成指定大小文件的示例详解

    这篇文章主要为大家详细介绍了Python如何实现生成指定大小文件,例如txt/图片/视频/csv等,文中的示例代码讲解详细,需要的可以参考下
    2023-08-08
  • NumPy进行统计分析

    NumPy进行统计分析

    本文主要介绍了NumPy进行统计分析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • mac系统安装Python3初体验

    mac系统安装Python3初体验

    这篇文章主要介绍了mac系统安装Python3初体验,需要的朋友可以参考下
    2018-01-01
  • django模板获取list中指定索引的值方式

    django模板获取list中指定索引的值方式

    这篇文章主要介绍了django模板获取list中指定索引的值方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05

最新评论