本系列文章都是基于陈儒的Python源码剖析一书。
打开object.h 文件
typedef struct _object {
PyObject_HEAD
} PyObject;
上述代码定义了一个数据类型PyObject. 可以发现PyObject中就是PyObject_HEAD。
#define PyObject_HEAD \
_PyObject_HEAD_EXTRA \
Py_ssize_t ob_refcnt; \
struct _typeobject *ob_type;
可以发现 PyObject_HEAD 是一个宏定义。其中 _PyObject_HEAD_EXTRA也是一个宏定义。
#ifdef Py_TRACE_REFS
/* Define pointers to support a doubly-linked list of all live heap objects. */
#define _PyObject_HEAD_EXTRA \
struct _object *_ob_next; \
struct _object *_ob_prev;
#define _PyObject_EXTRA_INIT 0, 0,
#else
#define _PyObject_HEAD_EXTRA
#define _PyObject_EXTRA_INIT
#endif
在release编译模式下 Py_TRACE_REFS 是没有被定义的。所以根据条件编译的结果来说
_PyObject_HEAD_EXTRA 为空。所以PyObject可以表述为下面形式:
typedef struct _object {
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
} PyObject;
可以认为 ob_refcnt 是一个无符号的整形变量。ob_refcnt和python的垃圾回收相关的,代表了一个python对象被引用的次数。我们知道Python主要的垃圾回收方式是引用计数,当一个对象被引用的次数为0的时候判断这个对象是一个垃圾对象,然后标记这块内存为垃圾,被重复使用。
ob_type 是一个指针指向_typeobject 的数据。_typeobject代表这个python对象的类型,这也是Python实现多态和各种魔法函数的核心所在。在_typeobject中定义了各种函数指针的数组或者单个的函数指针,这些函数指针代表着此类Python对象所实现的Python内建的各种协议。当运行到Python的各种运算的时候触发这些函数的调用。在Python中我们可以认为任何的 *** 作符都是对应着一种函数。
PyObject可以指代任何Python对象,你可能会觉得如果用PyObject指代任何Python对象,那么其他的数据域到什么地方去了。其实这是C语言中使用C语言描述面向对象思想的一种惯用法。头两个字段的大小都是确定的,完全可以获取到这个对象的类型,然后通过类型完全可以获取到这个对象的大小,然后强行的转型就可以变成具体的类型。如果你使用过Java可以认为PyObject是一个抽象类其中具有两个固定的字段,然后和一堆的抽象方法,你完全可以使用Java实现Python的对象模型。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)