在Python中,一切东西都是对象,源自于PyObject。在cpython中,通过这两个文件实现:

cpython/Include/object.h

cpython/Objects/object.c

Python内置的Object

PyObject

我们先看object.h中PyObject的定义

#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;
// ...
#else
#define _PyObject_HEAD_EXTRA
// ...

typedef struct _object {
    _PyObject_HEAD_EXTRA
    Py_ssize_t ob_refcnt;
    struct _typeobject *ob_type;
} PyObject;

其中,_PyObject_HEAD_EXTRA是用于trace的宏定义,正常环境下为空。

在这里,我们看到了ob_refcnt,这是PyObject的引用计数,在上一节,我们看到的INCREF()操作,就是把这个值加一。

接着是一个_typeobject的指针,用来表示这个对象的类型。这个对象指针也在object.h 中定义,我们会在下文展开。

这两个成员组成了PyObject。Em...,看起来PyObject并没有存什么东西。

PyVarObject

我们接着看第二个结构体:PyVarObject 从命名上看,这是PyObject的不定长版本,他除了用ob_base表示PyObject外,还增加了ob_size表示了不定长对象的大小。

typedef struct {
    PyObject ob_base;
    Py_ssize_t ob_size; /* Number of items in variable part */
} PyVarObject;

Em...,好像也没什么,只是增加了一个ob_size变量,看起来像是一个描述不定长对象大小的成员。

看到这儿,不由得有几个问题:

  • ob_refcnt 这个引用计数是啥,怎么工作的?
  • PyObject就两个成员变量,那变量的值存在哪儿,比如变量x=1,这个1存在哪里?
  • 第二个成员变量,_typeobject* 是什么?

我们依次分析这些问题。

results matching ""

    No results matching ""