1. 程式人生 > >python原始碼PyObject簡單解析

python原始碼PyObject簡單解析

1. python一切皆物件, 物件定義object.h

/* 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;

/* PyObject_HEAD defines the initial segment of every PyObject. */
#define PyObject_HEAD                   \
    _PyObject_HEAD_EXTRA                \
    Py_ssize_t ob_refcnt;               \
    struct _typeobject *ob_type;

 /* Nothing is actually declared to be a PyObject, but every pointer to
 * a Python object can be cast to a PyObject*.  This is inheritance built
 * by hand.  Similarly every pointer to a variable-size Python object can,
 * in addition, be cast to PyVarObject*.
 */
typedef struct _object {
    PyObject_HEAD
} PyObject;

typedef struct {
    PyObject_VAR_HEAD
} PyVarObject;
PyObject包含了一個PyObject_HEAD, 任何python的物件都含他的指標

PyObject_HEAD包含一個雙向連結串列, 一個引用計算器, 一個物件描述(typeobject)

typeobject先不詳細展開, 反正他記錄了一個物件型別,屬性啥的

整數物件定義:

typedef struct {
    PyObject_HEAD
    long ob_ival;
} PyIntObject;

list物件定義:
typedef struct {
    PyObject_VAR_HEAD
    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;

    /* ob_item contains space for 'allocated' elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size
     *     ob_item == NULL implies ob_size == allocated == 0
     * list.sort() temporarily sets allocated to -1 to detect mutations.
     *
     * Items must normally not be NULL, except during construction when
     * the list is not yet visible outside the function that builds it.
     */
    Py_ssize_t allocated;
} PyListObject;
其他dict, 成千上萬的自定義物件都是PyObject擴充套件屬性
Python物件的多型特性就是所有物件都是PyObject*, 具體的物件是根據ob_type域動態的進行判斷

解析整數物件:

1. python 的引用計數機制, 整數物件引用特別頻繁, 會不會頻繁的申請釋放記憶體

2. 所有的內建物件都有都通過一定的機制關聯

3. 小整數物件池, 一塊NSMALLPOSTNTS 長度的陣列, py2.7是257

4. 大整數物件:開闢一個數組(長度是82), 把陣列轉成單向連結串列, 表頭是free_list,當free_list為空, 則需要申請新的block

5. 當刪除一個大整數時(垃圾回收時), 並不是釋放記憶體, 而是讓free_list指向他:


如果-200的也收回,則只需維護指標指向即可,空閒記憶體就是連續的了