博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python 中的metaclass和baseclasses
阅读量:5159 次
发布时间:2019-06-13

本文共 3758 字,大约阅读时间需要 12 分钟。

提前说明:

        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 dictattrs = {'__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__=MyMetaclass	def __init__(self, arg):		super(UseMetaclass, self).__init__()		self.arg = arg				print type(UseMetaclass)#

  

  

 

  这个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__==
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 passed in a base that was not a class (such the random module instead of the random.random type). Help them out with by 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

你可能感兴趣的文章
添加了click事件不响应
查看>>
Excel导出失败的提示
查看>>
汇编指令
查看>>
Mysql数据库中InnoDB和MyISAM的差别
查看>>
Java并发编程:深入剖析ThreadLocal
查看>>
IPC进程通信机制
查看>>
bat文件调用php文件
查看>>
很有用的Jquery代码片段(转)
查看>>
bzoj2018年5月赛
查看>>
OperationalError:(1054 - "Unknown column 'game.lable1' in 'field list' ")解决办法
查看>>
震惊!小学生的300道四则运算题目竟然是这样做出来的!
查看>>
百度BAE环境下WordPress安装教程
查看>>
windows索引服务
查看>>
Linux学习之CentOS(十三)--CentOS6.4下Mysql数据库的安装与配置
查看>>
微信支付结果通用通知
查看>>
Android API Guides---Tasks and Back Stack
查看>>
Android中Handler使用浅析
查看>>
搜狗语音云开发入门(二)——使用离线语音识别服务
查看>>
C - The C Answer (2nd Edition) - Exercise 1-4
查看>>
转载的吐槽文
查看>>