python type 与 metaclass理解
简介
众所周知,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默认是所有类的元类;由isinstance与type之间的对比来看,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理解的更多相关文章
- python——type()、metaclass元类和精简ORM框架
1.type()函数 if __name__ == '__main__': h = hello() h.hello() print(type(hello)) print(type(h)) Hello, ...
- Python type class metaclass
'type' 是 python built-in metaclass 其他继承自 ‘type’的class都可以是 Metaclass 子类可以继承父类的metaclass 然而 __metaclas ...
- python元类:type和metaclass
python元类:type和metaclass python中一切皆对象,所以类本身也是对象.类有创建对象的能力,那谁来创建类的呢?答案是type. 1.用tpye函数创建一个类 class A(ob ...
- python 元类——metaclass
from stack overflow:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python Classes ...
- Python Type Hint类型注解
原文地址:https://realpython.com/python-type-checking/ 在本指南中,你将了解Python类型检查.传统上,Python解释器以灵活但隐式的方式处理类型.Py ...
- Python中文字符的理解:str()、repr()、print
Python中文字符的理解:str().repr().print 字数1384 阅读4 评论0 喜欢0 都说Python人不把文字编码这块从头到尾.从古至今全研究通透的话是完全玩不转的.我终于深刻的理 ...
- Python type类具体的三大分类:metaclasses,classes,instance
Python type类视角中的对象体系需要我们不断的学习,其中我们使用的时候需要注意.下面我们就看看如何才能更好的运用Python type类.下面的文章希望大家有所收获. 在单纯的Python t ...
- python 导入模块 import 理解
--python 导入模块 import 理解 -----------------------------------2014/03/18 python 导入一个模块的过程要求有一个叫做“路径搜索”的 ...
- 【python进阶】深入理解系统进程2
前言 在上一篇[python进阶]深入理解系统进程1中,我们讲述了多任务的一些概念,多进程的创建,fork等一些问题,这一节我们继续接着讲述系统进程的一些方法及注意点 multiprocessing ...
随机推荐
- 谈谈最近玩的设计软件:Figma 与 Sketch
谈谈最近玩的设计软件:Figma 与 Sketch 本文写于 2020 年 5 月 9 日 作为一个优秀的开发者,不懂设计是绝对不行的! 毕竟不懂设计的程序员不是好老板. 而做设计,早已不是尺规作图的 ...
- CI/CD介绍以及jenkins安装 1.1
一 .CI/CD介绍 互联网软件开发和发布,形成了一套流程标准,分为几个阶段:编码,构建,集成,测试,交付,部署 持续集成(continuous integration).持续交付(conti ...
- JavaScript 模块的循环加载(循环依赖问题分析)
简介 "循环加载"(circular dependency)指的是,a 脚本的执行依赖 b 脚本,而 b 脚本的执行又依赖 a 脚本. 分析 使用 madge 工具进行循环加载分析 ...
- 个人冲刺(四阶段)——体温上报app(一阶段)
任务:完成了后台数据库的类模块 MyDBHelper.java package com.example.helloworld; import android.content.Context; impo ...
- 安装Supervisor到CentOS(YUM)
Supervisor是一个Linux下进程管理工具. Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为守护进程,并监控进程状态,异常退出时能自动重启,可以 ...
- webpack基础知识介绍
1.开发模式 开发模式顾名思义就是我们开发代码时使用的模式 webpack默认只处理js文件,对样式是没办法处理的.因此要处理css资源需要引入CSS-loader 处理CSS资源 如果要使用 css ...
- 分布式机器学习:逻辑回归的并行化实现(PySpark)
1. 梯度计算式导出 我们在博客<统计学习:逻辑回归与交叉熵损失(Pytorch实现)>中提到,设\(w\)为权值(最后一维为偏置),样本总数为\(N\),\(\{(x_i, y_i)\} ...
- 深度学习与CV教程(6) | 神经网络训练技巧 (上)
作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/37 本文地址:http://www.showmeai.tech/article-det ...
- linux运维基础1
内容概要 运维简介 运维岗位职责 服务器 服务器硬件介绍 磁盘阵列 虚拟化软件及环境 虚拟化软件 安装操作系统 Vmware虚拟机安装及相关配置流程 内容详情 运维简介 运维岗位职责 核心:运行维护应 ...
- rpc的正确打开方式|读懂Go原生net/rpc包
前言 最近在阅读字节跳动开源RPC框架Kitex的源码,分析了如何借助命令行,由一个IDL文件,生成client和server的脚手架代码,也分析了Kitex的日志组件klog.当然Kitex还有许多 ...