提前说明:

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相关推荐

  1. [链接]Python中的metaclass、装饰器

    深刻理解Python中的元类(metaclass) Python装饰器学习(九步入门)

  2. python中metaclass的理解

    metaclass --元类, 为描述类的超类,同时可以改变子类的形态.metaclass就是Python中用来创建class object的class.我们可以将其看做能够产生class的类工厂. ...

  3. python中的__new__和__init__

    一.__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候. 这样便是__init ...

  4. Python中的__new__()方法的使用

    __new__() 函数只能用于从object继承的新式类. 先看下object类中对__new__()方法的定义: class object:   @staticmethod # known cas ...

  5. 浅谈 Python 中的 __init__ 和 __new__

    2019独角兽企业重金招聘Python工程师标准>>> 1.__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,_ ...

  6. Python中__init__和__new__的区别详解

    __init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候.例如: # -*- cod ...

  7. [转]深刻理解Python中的元类(metaclass)

    类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Pytho ...

  8. Python中的元类(metaclass)

    类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Pytho ...

  9. 深刻理解Python中的元类(metaclass)以及元类实现单例模式

    在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例模式的那一节有些疑惑.因此花了几天时间研究下元类这个概念.通过学习元类,我对pyt ...

最新文章

  1. 看职场老人教你如何平稳度过职场“更年期”
  2. 你已经用上 5G 网络了吗?
  3. 变频器服务器电路板维修,变频器线路板常见维修方法
  4. groupby索引有效吗_SQL IN 一定走索引吗?
  5. 分布式服务框架gRPC
  6. C语言fwrite()与Java writeFloat()数据转换
  7. 极速安装JumpServer - 官方文档版
  8. 【编译原理笔记10】语法制导翻译:在递归预测过程中进行翻译,L属性定义的自底向上翻译
  9. C++ 多线程下的单例模式
  10. jemalloc优化MySQL、Nginx内存管理
  11. java生成的条形码扫不了_JAVA 生成扫描条形码
  12. 新cBSS灰度发布Git管理流程
  13. 2021-09-20德天老师更新好学易懂的python办公自动化批量生成docx
  14. [论文分享] Stegozoa: Enhancing WebRTC Covert Channels with Video Steganography for Internet Censorship
  15. 九. MySQL InnoDB 底层结构
  16. java的框架_java 三大框架——spring
  17. 如何在 Python 中将 Excel 文件转换为图像?Aspose快速搞定
  18. onkeypress 、onkeyup 与onkeydown三者之间的区别
  19. Matlab TRL校准(简易版)
  20. java基础国庆作业_0715于昊-国庆作业.md

热门文章

  1. web前端是什么?需要掌握什么技术?
  2. 素数类型C语言题目总结
  3. android 自定义控件 焦点,Android 自定义Button按钮显示样式(正常、按下、获取焦点)...
  4. nvidia的jetson系列的方案_NVIDIA Jetson 平台
  5. flask 模板 php,Flask 模板系统
  6. 卷积神经网络中的池化方法(pooling)总结
  7. (二)使用预定义模型 QStringListModel例子
  8. 【转】QTableView 小结
  9. php上传文件 报的错误 $_FILES[‘file’]['error']
  10. iOS逆向工程- 工具详解