简介

众所周知,type在一般情况下,我们都会去获取一个对象的类型,然后进行类型的比较;除此之外,type还有一个不为人知的作用:动态的创建类。在了解这个之前,首先了解以下type和isinstance之间的关系或者说是区别,这两个方法都可以判断类型,但又有所区别

type与isinstance

class Person:
def __init__(self) -> None:
pass def sleep(self):
print("sleep") class Male(Person):
def __init__(self) -> None:
pass def sleep(self):
print("sleep") print(type(Person))
print(type(Male))
print(isinstance(Person, type))
print(isinstance(Male, type))
p = Person()
m = Male()
print(type(p))
print(type(m))
print(type(p) == type(m))
print(isinstance(p, Person))
print(isinstance(m, Male))
print(isinstance(m, Person))
<class 'type'>
<class 'type'>
True
True
<class '__main__.Person'>
<class '__main__.Male'>
False
True
True
True

由结果<class 'type'>可以看出,所有的类默认是继承自type类,也就是说type默认是所有类的元类;由isinstancetype之间的对比来看,isinstance会考虑到继承关系,但是type不会考虑到继承关系,通俗点讲就是,对于子类与父类的对象类型比较时,isinstance会认为是相同的,但是type会认为不是相同的。

因此建议在比较对象类型时最好使用isinstance方法。

如何动态创建一个类?

由上述可知,type默认是所有类的元类,因此我们可以使用type创建一个简单的类:

type(__name: str, __bases: tuple[type, ...], __dict: dict[str, Any])
  • __name:类的名称
  • __bases:继承的类,以元组形式,注意单个元素时需要在后面添加逗号
  • __dict:类中的属性或者方法

    详细代码如下:
def run(self):
print("run" class_name = "Test"
base_name = object
name = "tom"
Person2 = type(
class_name,
(base_name,),
{"run": run, "name": name},
) print(type(Person2))
p = Person2()
print(type(p))
p.run()
<class 'type'>
<class '__main__.Test'>
run

metaclass作用

当我们需要对一种类型的类批量添加某些属性或者方法时,使用metaclass创建元类的派生类,从而添加属性或者方法

class FirstMetaClass(type):
# cls代表动态修改的类
# name代表动态修改的类名
# bases代表被动态修改的类的所有父类
# attr代表被动态修改的类的所有属性、方法组成的字典
def __new__(cls, name, bases, attrs):
# 动态为该类添加一个name属性
attrs['name'] = "C语言中文网"
attrs['say'] = lambda self: print("调用 say() 实例方法")
return super().__new__(cls, name, bases, attrs) class Test(metaclass=FirstMetaClass):
def __init__(self) -> None:
pass def __call__(self, *args, **kwds):
pass t = Test()
print(t.name)
t.say()
C语言中文网
调用 say() 实例方法

由上述看出,当指定了元类后,添加的属性可以直接调用,类似于子类可以直接调用父类的方法一样,其实元类就相当于时每个类的父类,因此修改元类属性或者方法,可以影响到子类,父类与子类的关系和元类与普通类的关系是类似的。

python type 与 metaclass理解的更多相关文章

  1. python——type()、metaclass元类和精简ORM框架

    1.type()函数 if __name__ == '__main__': h = hello() h.hello() print(type(hello)) print(type(h)) Hello, ...

  2. Python type class metaclass

    'type' 是 python built-in metaclass 其他继承自 ‘type’的class都可以是 Metaclass 子类可以继承父类的metaclass 然而 __metaclas ...

  3. python元类:type和metaclass

    python元类:type和metaclass python中一切皆对象,所以类本身也是对象.类有创建对象的能力,那谁来创建类的呢?答案是type. 1.用tpye函数创建一个类 class A(ob ...

  4. python 元类——metaclass

    from stack overflow:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python Classes ...

  5. Python Type Hint类型注解

    原文地址:https://realpython.com/python-type-checking/ 在本指南中,你将了解Python类型检查.传统上,Python解释器以灵活但隐式的方式处理类型.Py ...

  6. Python中文字符的理解:str()、repr()、print

    Python中文字符的理解:str().repr().print 字数1384 阅读4 评论0 喜欢0 都说Python人不把文字编码这块从头到尾.从古至今全研究通透的话是完全玩不转的.我终于深刻的理 ...

  7. Python type类具体的三大分类:metaclasses,classes,instance

    Python type类视角中的对象体系需要我们不断的学习,其中我们使用的时候需要注意.下面我们就看看如何才能更好的运用Python type类.下面的文章希望大家有所收获. 在单纯的Python t ...

  8. python 导入模块 import 理解

    --python 导入模块 import 理解 -----------------------------------2014/03/18 python 导入一个模块的过程要求有一个叫做“路径搜索”的 ...

  9. 【python进阶】深入理解系统进程2

    前言 在上一篇[python进阶]深入理解系统进程1中,我们讲述了多任务的一些概念,多进程的创建,fork等一些问题,这一节我们继续接着讲述系统进程的一些方法及注意点 multiprocessing ...

随机推荐

  1. Mysql limit 优化优化

    MySql 性能到底能有多高?用了php半年多,真正如此深入的去思考这个问题还是从前天开始.有过痛苦有过绝望,到现在充满信心! MySql 这个数据库绝对是适合dba级的高手去玩的,一般做一点1万篇新 ...

  2. [保姆级教程] 如何在 Linux Kernel (V5.17.7) 中添加一个系统调用(System call)

    最近在学习 <linux Kernel Development>,本书用的linux kernel 是v2.6 版本的.看完"系统调用"一节后,想尝试添加一个系统调用, ...

  3. python之贪婪算法

    贪婪算法 贪婪算法也称为最优算法,这种算法并不是最准确的答案,但确认最接近答案的近似算法. 这时候有人会问,不是最准确的答案我要她干嘛?但是在日常中,我们有时候会遇到一些我们无法处理的问题,甚至是要花 ...

  4. AJAX——POST请求

    POST.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  5. 2022Gartner容器预测:2025年85%的企业将使用容器管理服务

    近日,国际知名权威分析机构Gartner发布了最新<全球容器管理预测>.预测中指出:在加速的数字化转型驱动下,到2025年全球容器管理领域市场规模将突破14亿美元,预计年复合增长率将达到2 ...

  6. 【Java面试】说说你对Spring MVC的理解

    一个工作了7年的粉丝,他说在面试之前,Spring这块的内容准备得很充分. 而且各种面试题也刷了,结果在面试的时候,面试官问:"说说你对Spring MVC的理解". 这个问题一下 ...

  7. Python Selenium库

    Selenium库 自动化测试工具,支持多种游览器 爬虫中主要用来解决JavaScript渲染的问题 安装Selenium pip3 install selenium 安装游览器驱动 下载驱动地址:h ...

  8. neo4j中重复节点问题

    neo4j中重复节点问题 neo4j中,在导入csv文件时,可能会出现有重复节点的现象.可以分为以下步骤解决:1.先查看下某个标签下的节点总数match (n:PERSON) return count ...

  9. Python参数传递中的 args, kwargs

    概念 真正的Python参数传递语法是*和**,其被称为 被称为打包和解包参数.*args和**kwargs只是大家默认的一种形式.也可以写成*keys和**kkeys等其他形式.二者都是为了在不知道 ...

  10. js 表面学习 - 认识函数

    JavaScript 函数语法 JavaScript 函数通过 function 关键词进行定义,其后是函数名和括号 (). 函数名可包含字母.数字.下划线和美元符号(规则与变量名相同). 圆括号可包 ...