首页 > 编程语言 >【Python】type、isinstance、issubclass详解

【Python】type、isinstance、issubclass详解

时间:2023-01-28 16:02:20浏览次数:45  
标签:__ name Python issubclass isinstance type class cls

【Python】type、isinstance、issubclass详解

大家好,我们的gzh是朝阳三只大明白,满满全是干货,分享近期的学习知识以及个人总结(包括读研和IT),跪求一波关注,希望和大家一起努力、进步!!

type

​type​​方法有两种重载形式:

  1. ​type(o: object)​​;
  2. ​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)。

有几点注意事项这里说一下:

  1. ​issubclass(cls, cls)​​返回是真;
  2. 【classinfo】参数可以是一个type元祖,只要有一个条件为真,则表达式结果为真;
  3. 【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

从程序结果可以看到传入元类和类返回永远是假,并且不能直接传入对象。

综合示例

为了更好的让大家明白这三者之间的区别和联系,我画了一张图

【Python】type、isinstance、issubclass详解_python入门

这是初始状态,定义了三个对象,三个类和三个元类,它们之间的关系如上图所示;

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】为例,它的检索范围如下图红线所示:

【Python】type、isinstance、issubclass详解_python入门_02

针对类

以【C3】为例,它的检索范围如下图红线所示:

【Python】type、isinstance、issubclass详解_python_03

issubclass

针对类

以【C2】为例,返回真值的范围如下:

【Python】type、isinstance、issubclass详解_python入门_04

针对元类

以【M2】为例,返回真值的范围如下:

【Python】type、isinstance、issubclass详解_python基础_05

总结

调用​​type​​方法

  1. 如果是对象,则会顺着实例化的逆方向寻找,也就是找到创建它的类;
  2. 如果是类,则会顺着继承逆方向寻找,直到找到它的元类。

调用​​isinstance​​方法

  1. 如果是对象,那么实例化它的类和该类的所有父类都返回真,也就是沿着继承路径上都是返回真,但 不能是元类;
  2. 如果是类,那么就找其元类的继承路径,路径上所有的元类都返回真。

调用​​issubclass​​方法

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

文中难免会出现一些描述不当之处(尽管我已反复检查多次),欢迎在留言区指正,相关的知识点也可进行分享,希望大家都能有所收获!!

标签:__,name,Python,issubclass,isinstance,type,class,cls
From: https://blog.51cto.com/u_15945763/6024975

相关文章

  • 【Python】python深拷贝和浅拷贝(一)
    【Python】python深拷贝和浅拷贝(一)大家好,我们的gzh是朝阳三只大明白,满满全是干货,分享近期的学习知识以及个人总结(包括读研和IT),跪求一波关注,希望和大家一起努力、进步!!定义直......
  • 【Python】python深拷贝和浅拷贝(二)
    【Python】python深拷贝和浅拷贝(二)大家好,我们的gzh是朝阳三只大明白,满满全是干货,分享近期的学习知识以及个人总结(包括读研和IT),跪求一波关注,希望和大家一起努力、进步!!前言上......
  • python图片拼接
     首先我们来尝试将分片的图片复原为正常的图片这里是六张切成小细条的图片,原本是一张大图的,现在我们用python将他们合并到一块,题外话图片来源于中华连环画,*http://www......
  • 【Python学习002】函数参数
    我们的gzh是【朝阳三只大明白】,满满全是干货,分享近期的学习知识以及个人总结(包括读研和IT),希望大家一起努力,一起加油!求关注!!概述函数是组织好的、可重复使用的,用来实现单一,或......
  • 上古神兵,先天至宝,Win11平台安装和配置NeoVim0.8.2编辑器搭建Python3开发环境(2023最
    毫无疑问,我们生活在编辑器的最好年代,Vim是仅在Vi之下的神级编辑器,而脱胎于Vim的NeoVim则是这个时代最好的编辑器,没有之一。异步支持、更好的内存管理、更快的渲染速度、更......
  • python对接API二次开发高级实战案例解析:百度地图Web服务API封装函数(行政区划区域检索
    文章目录​​前言​​​​一、IP定位​​​​1.请求URL​​​​2.获取IP定位封装函数​​​​3.输出结果​​​​二、国内天气查询​​​​1.请求url​​​​2.天气查询封装......
  • colab在更换python包版本时,如何正确重启
    当我在使用Node2Vec这个包的时候,遇到了gem和numpy的版本冲突问题。最后在pc上测试,发现只要升级numpy就能解决问题。但是在colab中更新numpy版本依旧报错。后面才发现,就算在c......
  • Python爬虫实践代码示例
    对于刚入门爬虫的小伙伴来说,累积经验多练习代码是非常有必要的,下面就是有关爬虫的一些小案例,欢迎大家指正。importrequestsfrombs4importBeautifulSoup#importpandas......
  • Python入门之转义符
    """转义符:改变原始字符含义的特殊符号"""#不支持所见即所得name="黎二狗"name='黎二狗'#可见即所得name='''黎二狗'''name="""黎......
  • python入门之str/ord/chr
    """字符串(str):由一系列字符组成的不可变系列容器,存储的是字符的编码值。编码:1.字节byte:计算机最小存储单位,等于8位bit。(bitBKBMBGT)2.字符:单个的数......