Python 对象的基石 PyObject

Python 对象的基石 PyObject,第1张

本系列文章都是基于陈儒的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的对象模型。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/916870.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存