# 关键源码

# structs

# PyObject

typedef struct _object {
    _PyObject_HEAD_EXTRA 		/* 实现双向链表-用于跟踪活跃队对象以阿布呢不启用 */
    Py_ssize_t ob_refcnt;
    struct _typeobject *ob_type;	/* 类型指针 */
} PyObject;
/*
typedef struct {
    PyObject_HEAD

    double ob_fval;
} PyFloatObject;
*/

# PyVarObject

  • 相比于普通对象多了一个ob_size字段用于记录元素个数
  • 注意一般是用于存储相同类型的容器,对于str这种底层存储会变化的结构实际上采用的是PyObject结构体。
typedef struct {
    PyObject ob_base;
    Py_ssize_t ob_size; 		/* 长度信息 */
} PyVarObject;
/*
typedef struct {
    PyObject_VAR_HEAD

    PyObject **ob_item;
    Py_ssize_t allocated;       	// 实际已分配长度-容量 
} PyListObject;
*/

# PyTypeObject

  • 保存对象的元信息,描述对象的类型、内存信息、支持的操作等

  • PyObject中ob_type指针的指向

  • 一般类型对象只会在实例化一个作为全局变量-例如PyType_Type

    • PyType_Type​的tp_name​是"type"-它自己
//cpython-v3.7.4\Doc\includes\typestruct.h
typedef struct _typeobject {
    PyObject_VAR_HEAD
    const char *tp_name; /* For printing, in format "<module>.<name>" */
    Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */

    /* Methods to implement standard operations */

    destructor tp_dealloc;
    printfunc tp_print;
    getattrfunc tp_getattr;
    setattrfunc tp_setattr;
    PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)
                                    or tp_reserved (Python 3) */
    reprfunc tp_repr;

    /* 标准操作集: Method suites for standard classes */

    PyNumberMethods *tp_as_number;
    PySequenceMethods *tp_as_sequence;
    PyMappingMethods *tp_as_mapping;

    /* More standard operations (here for binary compatibility) */

    hashfunc tp_hash;
    ternaryfunc tp_call;
    reprfunc tp_str;
    getattrofunc tp_getattro;
    setattrofunc tp_setattro;

    /* Functions to access object as input/output buffer */
    PyBufferProcs *tp_as_buffer;

    /* Flags to define presence of optional/expanded features */
    unsigned long tp_flags;

    const char *tp_doc; /* Documentation string */

    /* call function for all accessible objects */
    traverseproc tp_traverse;

    /* delete references to contained objects */
    inquiry tp_clear;

    /* rich comparisons */
    richcmpfunc tp_richcompare;

    /* weak reference enabler */
    Py_ssize_t tp_weaklistoffset;

    /* Iterators */
    getiterfunc tp_iter;
    iternextfunc tp_iternext;

    /* Attribute descriptor and subclassing stuff */
    struct PyMethodDef *tp_methods;
    struct PyMemberDef *tp_members;
    struct PyGetSetDef *tp_getset;
    struct _typeobject *tp_base;
    PyObject *tp_dict;
    descrgetfunc tp_descr_get;
    descrsetfunc tp_descr_set;
    Py_ssize_t tp_dictoffset;
    initproc tp_init;
    allocfunc tp_alloc;
    newfunc tp_new;
    freefunc tp_free; /* Low-level free-memory routine */
    inquiry tp_is_gc; /* For PyObject_IS_GC */
    PyObject *tp_bases;
    PyObject *tp_mro; /* method resolution order */
    PyObject *tp_cache;
    PyObject *tp_subclasses;
    PyObject *tp_weaklist;
    destructor tp_del;

    /* Type attribute cache version tag. Added in version 2.6 */
    unsigned int tp_version_tag;

    destructor tp_finalize;

} PyTypeObject;

// PyTypeObject PyType_Type = {			/* 全局唯一的实例
//     PyVarObject_HEAD_INIT(&PyType_Type, 0)	 /* ob_type指向自己 */
//     "type",                                     /* tp_name */
//     sizeof(PyHeapTypeObject),                   /* tp_basicsize */
//     sizeof(PyMemberDef),                        /* tp_itemsize */
//     (destructor)type_dealloc,                   /* tp_dealloc */

//     // ...
//     (reprfunc)type_repr,                        /* tp_repr */

//     // ...
// };

// PyTypeObject PyBaseObject_Type = {
//     PyVarObject_HEAD_INIT(&PyType_Type, 0)	/* ob_type指向PyType_Type */
//     "object",                                   /* tp_name */
//     sizeof(PyObject),                           /* tp_basicsize */
//     0,                                          /* tp_itemsize */
//     object_dealloc,                             /* tp_dealloc */

//     // ...
//     object_repr,                                /* tp_repr */
// };

#

# _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

# PyObject_HEAD && PyObject_VAR_HEAD

#define PyObject_HEAD          PyObject ob_base;
#define PyObject_VAR_HEAD      PyVarObject ob_base;

# PyObject_HEAD_INIT(type) && PyVarObject_HEAD_INIT

  • 用于初始化对象头部
#define PyObject_HEAD_INIT(type)        \
    { _PyObject_EXTRA_INIT              \
    1, type },

#define PyVarObject_HEAD_INIT(type, size)       \
    { PyObject_HEAD_INIT(type) size },

# Py_INCREF&&Py_DECREF

#define Py_INCREF(op) (                         \
    _Py_INC_REFTOTAL  _Py_REF_DEBUG_COMMA       \
    ((PyObject *)(op))->ob_refcnt++)
#define Py_DECREF(op)                                   \
    do {                                                \
        PyObject *_py_decref_tmp = (PyObject *)(op);    \
        if (_Py_DEC_REFTOTAL  _Py_REF_DEBUG_COMMA       \
        --(_py_decref_tmp)->ob_refcnt != 0)             \
            _Py_CHECK_REFCNT(_py_decref_tmp)            \
        else                                            \
            _Py_Dealloc(_py_decref_tmp);                \
    } while (0)

# PyObject_INIT

#define PyObject_INIT(op, typeobj) \
    ( Py_TYPE(op) = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )

# _Py_NewReference

  • 初始化对象引用计数为1
#define _Py_NewReference(op) (                          \
    _Py_INC_TPALLOCS(op) _Py_COUNT_ALLOCS_COMMA         \
    _Py_INC_REFTOTAL  _Py_REF_DEBUG_COMMA               \
    Py_REFCNT(op) = 1)

# _Py_Dealloc

#define _Py_Dealloc(op) (                               \
    _Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA          \
    (*Py_TYPE(op)->tp_dealloc)((PyObject *)(op)))

# function

# PyMem_Realloc

PyMem_Realloc用于对动态内存进行扩容或者缩容,关键步骤如下:

  1. 新申请一块尺寸为 new_size 的内存区域;
  2. 将数据从旧内存区域 ptr 拷贝到新内存区域;
  3. 释放旧内存区域 ptr ;
  4. 返回新内存区域。

image

void *
PyMem_Realloc(void *ptr, size_t new_size)
{
    /* see PyMem_RawMalloc() */
    if (new_size > (size_t)PY_SSIZE_T_MAX)
        return NULL;
    return _PyMem.realloc(_PyMem.ctx, ptr, new_size);
}