一文带你了解Python中的type,isinstance和issubclass
作者:勇敢努力拼搏 发布时间:2023-05-10 22:54:20
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】为例,返回真值的范围如下:
参数必须是同一个类型,元类或者类;
按照继承路径进行判断。
来源:https://juejin.cn/post/7193577879345561657
猜你喜欢
- 运行环境IDE丨pycharm版本丨Python3.6系统丨Windows实现目的与思路目的实现对腾讯视频目标url的解析与下载,由于第三方
- 三元条件判断的3种实现方法C语言中有三元条件表达式,如 a>b?a:b,Python中没有三目运算符(?:),但Python有它自己的
- 无论安装何版本的mysql,在管理工具的服务中启动mysql服务时都会在中途报错。内容为:在 本地计算机 无法启动mysql服务 错误106
- 目录项目引入flask-sqlalchemyORM简介及模型定义表关系类型及编码实现一对多关系(多对一关系)一对一关系多对多关系数据库基本操
- 这篇文章主要介绍了Pandas数据离散化原理及实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋
- 1:readline()file = open("sample.txt") while 1: line =
- 一:操作session1:session配置Session 的配置文件存储在config/session.php中,配置参数有:(1):配置
- 如何制作一个弹出式的调查窗口?执行下面这段ASP代码: <% &n
- 我们经常见到很多网站留言系统的显示访客的IP地址都是隐藏了一部分,以达到隐蔽访客真实地理位置的功能。如:111.222.333.*,当然在系
- 跨文件使用全局变量有多个py文件同时使用一个全局变量时,那应该如何使跨文件,用这个全局变量呢?1. 错误示范file1.py代码如下:num
- Django学习笔记-学生管理系统(Django实现)笔记中仅实现了对数据的全部查询。下面实现新增、删除、修改,代码如下。下面的代码没有对输
- 前言什么是树表查询?借助具有特殊性质的树数据结构进行关键字查找。本文所涉及到的特殊结构性质的树包括:二叉排序树。平衡二叉树。使用上述树结构存
- 1.列表(List)元组是由一对方括号构成的序列。列表创建后,可以根据自己的需要改变他的内容>>> list=[1,2,3
- os.remove不能用来删除文件夹,否则拒绝访问。# -*- coding:utf-8 -*-import osif __name__ =
- 一.准备工作首先,本文使用的技术为 python+requests+bs4,没有了解过可以先去了解一下。我们的需求是将博客园问题列表中的所有
- 一、前言经过前面的两篇文章,整体工作已经完成了2/3了,剩下的1/3,将会在本片文章提及前面两步文章链接python实战之德州扑克第一步-发
- SQL Server管理,你做得好吗?下文这些可能会对你的工作有一些帮助,不妨耐心的看看吧。1. 数据库文件有.mdf .ndf .ldf三
- 在采集网页信息的时候,经常需要伪造报头来实现采集脚本的有效执行下面,我们将使用urllib2的header部分伪造报头来实现采集信息方法1、
- Harris 角点检测算法1. 角点角点是水平方向、垂直方向变化都很大的像素。角点检测算法的基本思想:
- Python应用编程需要用到的针对不同数据库引擎的数据库接口:http://wiki.python.org/moin/DatabaseInt