对PyObject的认识

来源:互联网 发布:软件测试缺陷分析报告 编辑:程序博客网 时间:2024/04/28 03:24

最近一直在看《python源码剖析》,现在将自己的认识一步步记录下来,既方便大家分享讨论,共同进步,也方便我自己以后的回顾复习

对象是Python中非常重要的一个概念,需要明确的是在Python中任何事物都是对象(包括类型对象,yes,10是一个对象,10的类型int也是一个对象).我们知道,python是用c来实现的,那么具体这个对象在源代码里面是怎么表示的呢?


PyObject非常简单,这个struct只包含两个元素,一个是用来记录引用次数的(以此来做垃圾回收,但不是引用为0就会释放空间,还有内存池这个玩意),另一个用来指明这个对象的type.这是所有python object共有的一部分,所以在源代码内部相互传递对象的时候,所有对象都能用PyObject*来表示,非常简洁明了,同时这个ob_type指明了这个对象的类型,从而实现了c语言不提供但c++提供的多态特性(里面用大量的函数指针实现)

Python对象分定长和不定长。定长的,可想而知,int这种肯定是,sizeof(1)和sizeof(10)肯定是一样的,那么不定长的呢,也很容易想到,c++里面的string嘛,“x"和”world"这两个肯定长度不一样。那Python是怎么表示这两种类型的呢?下面是不定长的源码:



其中PyObject_HEAD指的就是PyObject,也就是说只多了一个ob_size这么一个标记,这个标记是用来表示这个变长对象内部元素的个数,比如list a[1,2,3]的ob_size是3,注意不是指的占用内存的大小,而是元素个数。


不同的对象肯定会有不同的大小,在这些对象创建的时候计算机怎么知道分配给他们多少内存?分配多少内存的信息隐藏在ob_type里面,如果我们知道了某个对象的类型,那么不就可以分配合适大小的内存了么.来看一下类型对象的定义:



包含了PyObject_VAR_HEAD,说明它也是一个PyObject. 其中tp_basicsize和tp_itemsize就是用来说明分配多少内存的。接下来是一系列的函数指针,和上面提到的多态特性有关。


前面说过,类型对象的类型也是类型,下图可以说的很清楚:



也就是说10的类型是PyInt_Type,而PyInt_Type的类型则是PyType_Pype(所谓的metaclass),看下它的源码:



它其实是自己指向自己的(这点在我按照教程实现small python是时比较疑惑,为什么可以这样写?在创建PyType_Type的时候用了它的引用,什么原理?实现small python下次博客再写,^=^)。

初次写博客,有不正确的地方请见谅


原创粉丝点击