python 中的metaclass和baseclasses
提前说明:
class object 指VM中的class 对象,因为python一切对象,class在VM也是一个对象,需要区分class对象和 class实例对象。
class instance 指 某个class的 instance ,这个instance 的 ob_type指向某个 class object
python中 类对象有两种相关的class需要我们特别关注:
1.metaclass:
metaclass关乎class object(不是 class instance)的创建。
在python中一般class的metaclass是type这个typeobject。
用type创建class object 例子:
#class instance 初始化方法
def __myinit__(self,arg):print("__myinit__")self.arg=argdef classmethod1(self):print(self.arg)#class object's dict
attrs = {'__init__': __myinit__, 'classmethod1': classmethod1}
#基类
bases=(object,)ClassObject=type("ClassObject",bases,attrs)classInstance=ClassObject("abcde")
classInstance.classmethod1()
通过meataclass 来创建 classobject实例:
class MyMetaclass(type):def __new__(clz,name,bases,attrs):print("create new class ",name)return type.__new__(clz, name, bases, attrs)class UseMetaclass(object):__metaclass__=MyMetaclassdef __init__(self, arg):super(UseMetaclass, self).__init__()self.arg = argprint type(UseMetaclass)
#<class 'A.MyMetaclass'>
这个class在python层面对应的是 classname.__metaclass__这个对象,在C 源码层面就是 PyObject.ob_type这个对象了。
metaclass关乎 class object的创建
metaclass的确定次序:
1.定义类时是否有__metaclass__这个field
2.baseclasses[0]中是否有定义__metaclass__这个field,这个查找步骤会一直向父类baseclasses[0]递归
3.global名字空间中是否有__metaclass__这个field
4.实在都没有了(正常状态),__metaclass__就用PyClass_Type
static PyObject *
build_class(PyObject *methods, PyObject *bases, PyObject *name)
{PyObject *metaclass = NULL, *result, *base;//检查属性是否已经填了__metaclass__if (PyDict_Check(methods))metaclass = PyDict_GetItemString(methods, "__metaclass__");if (metaclass != NULL){/*print_obj(metaclass);printf("\n");*/Py_INCREF(metaclass);}else if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {//从第一个基类里找__metaclass__,就是第一个基类的ob_type了,base 一般会是object 就是 那个PyBaseObject_Type,所以base.ob_type 就是PyType_Type ,这个class 对象就是 metaclass了// object.__class__==<type 'type'>base = PyTuple_GET_ITEM(bases, 0);metaclass = PyObject_GetAttrString(base, "__class__");if (metaclass == NULL) {PyErr_Clear();metaclass = (PyObject *)base->ob_type;Py_INCREF(metaclass);}//print_obj(metaclass);}else {// 这个else 处理 classic 的类定义方式 PyObject *g = PyEval_GetGlobals();if (g != NULL && PyDict_Check(g))metaclass = PyDict_GetItemString(g, "__metaclass__");if (metaclass == NULL)metaclass = (PyObject *) &PyClass_Type;Py_INCREF(metaclass);}//以上代码都为弄到一个__metaclass__/*创建一个类型对象, 调用metaclass ,会调用到 metaclass的 tp_call ,然后 还会调用到 type_new 创建一个新的类型对象,metaclass 是一个callable的对象*/result = PyObject_CallFunctionObjArgs(metaclass, name, bases, methods,NULL);Py_DECREF(metaclass);if (result == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) {/* A type error here likely means that the user passedin a base that was not a class (such the random moduleinstead of the random.random type). Help them out withby augmenting the error message with more information.*/PyObject *ptype, *pvalue, *ptraceback;PyErr_Fetch(&ptype, &pvalue, &ptraceback);if (PyString_Check(pvalue)) {PyObject *newmsg;newmsg = PyString_FromFormat("Error when calling the metaclass bases\n"" %s",PyString_AS_STRING(pvalue));if (newmsg != NULL) {Py_DECREF(pvalue);pvalue = newmsg;}}PyErr_Restore(ptype, pvalue, ptraceback);}return result;
}
2.baseclasses:
这个class就是所谓的基类了。
用class.mro()获取所有基类,这个返回的集合中从 序号1开始才是真正所谓的基类。
转载于:https://www.cnblogs.com/hi0xcc/p/5580262.html
python 中的metaclass和baseclasses相关推荐
- [链接]Python中的metaclass、装饰器
深刻理解Python中的元类(metaclass) Python装饰器学习(九步入门)
- python中metaclass的理解
metaclass --元类, 为描述类的超类,同时可以改变子类的形态.metaclass就是Python中用来创建class object的class.我们可以将其看做能够产生class的类工厂. ...
- python中的__new__和__init__
一.__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候. 这样便是__init ...
- Python中的__new__()方法的使用
__new__() 函数只能用于从object继承的新式类. 先看下object类中对__new__()方法的定义: class object: @staticmethod # known cas ...
- 浅谈 Python 中的 __init__ 和 __new__
2019独角兽企业重金招聘Python工程师标准>>> 1.__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,_ ...
- Python中__init__和__new__的区别详解
__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候.例如: # -*- cod ...
- [转]深刻理解Python中的元类(metaclass)
类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Pytho ...
- Python中的元类(metaclass)
类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Pytho ...
- 深刻理解Python中的元类(metaclass)以及元类实现单例模式
在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例模式的那一节有些疑惑.因此花了几天时间研究下元类这个概念.通过学习元类,我对pyt ...
最新文章
- 看职场老人教你如何平稳度过职场“更年期”
- 你已经用上 5G 网络了吗?
- 变频器服务器电路板维修,变频器线路板常见维修方法
- groupby索引有效吗_SQL IN 一定走索引吗?
- 分布式服务框架gRPC
- C语言fwrite()与Java writeFloat()数据转换
- 极速安装JumpServer - 官方文档版
- 【编译原理笔记10】语法制导翻译:在递归预测过程中进行翻译,L属性定义的自底向上翻译
- C++ 多线程下的单例模式
- jemalloc优化MySQL、Nginx内存管理
- java生成的条形码扫不了_JAVA 生成扫描条形码
- 新cBSS灰度发布Git管理流程
- 2021-09-20德天老师更新好学易懂的python办公自动化批量生成docx
- [论文分享] Stegozoa: Enhancing WebRTC Covert Channels with Video Steganography for Internet Censorship
- 九. MySQL InnoDB 底层结构
- java的框架_java 三大框架——spring
- 如何在 Python 中将 Excel 文件转换为图像?Aspose快速搞定
- onkeypress 、onkeyup 与onkeydown三者之间的区别
- Matlab TRL校准(简易版)
- java基础国庆作业_0715于昊-国庆作业.md
热门文章
- web前端是什么?需要掌握什么技术?
- 素数类型C语言题目总结
- android 自定义控件 焦点,Android 自定义Button按钮显示样式(正常、按下、获取焦点)...
- nvidia的jetson系列的方案_NVIDIA Jetson 平台
- flask 模板 php,Flask 模板系统
- 卷积神经网络中的池化方法(pooling)总结
- (二)使用预定义模型 QStringListModel例子
- 【转】QTableView 小结
- php上传文件 报的错误 $_FILES[‘file’]['error']
- iOS逆向工程- 工具详解