Python内建对象

阅读量: 鲁文奎 2021-04-22 12:04:49
Categories: Tags:

Python内建对象

对象机制的基石-PyObject

在Python中, 有"一切皆为对象"的说法, 而这些对象都拥有一些相同的内容, 这些内容就在PyObject中定义.
PyObject是整个Python对象机制的核心.
PyObject:

typedef struct _object {
    PyObject_HEAD
} PyObject;

PyObject_HEAD:

#define PyObject_HEAD                   \
    _PyObject_HEAD_EXTRA                \
    Py_ssize_t ob_refcnt;               \
    struct _typeobject *ob_type;

可以忽略_PyObject_HEAD_EXTRA, 这个是在调试的时候使用的.由此,我们可以得到真正的PyObject:

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

Py_ssize_t 等价于 int 类型, ob_refcnt和 Python的内存管理机制相关, 用来进行引用计数的.
_typeobject 是Python内部的一种特殊对象, 它是用来指定一个对象类型的类型对象.

PyObject中定义了每一个Python对象都必须有的内容, 这些内容将出现在每一个Python对象所占有的内存的最开始的字节中.
比如Python的int类型:

typedef struct {
    PyObject_HEAD
    long ob_ival;
} PyIntObject;

由此可知, int对象真正的内容保存在ob_ival中.

定长对象和变长对象

在Python中, 变长对象用PyVarObject来表示

typedef struct {
    PyObject_VAR_HEAD
} PyVarObject;
#define PyObject_VAR_HEAD               \
    PyObject_HEAD                       \
    Py_ssize_t ob_size; /* Number of items in variable part */

与PyObject相比, PyVarObject只是多了一个ob_size,而此变量是用来对PyVarObject中的元素进行计数的.

据上可知, 在Python中所有的对象都有一个相同的头部 PyObject,因此 我们只需要用一个PyObject*指针就可以引用任意的一个对象.

类型对象

对象占用的空间大小是对象的一种元信息, 这种信息存储在ob_type中, 也就是用_typeobject类型来表示相关信息.
在_typeobject的定义中包含了许多信息, 主要可以分为4类:

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;
    cmpfunc tp_compare;
    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 */
    long tp_flags;

    const char *tp_doc; /* Documentation string */

    /* Assigned meaning in release 2.0 */
    /* call function for all accessible objects */
    traverseproc tp_traverse;

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

    /* Assigned meaning in release 2.1 */
    /* rich comparisons */
    richcmpfunc tp_richcompare;

    /* weak reference enabler */
    Py_ssize_t tp_weaklistoffset;

    /* Added in release 2.2 */
    /* 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;

#ifdef COUNT_ALLOCS
    /* these must be last and never explicitly initialized */
    Py_ssize_t tp_allocs;
    Py_ssize_t tp_frees;
    Py_ssize_t tp_maxalloc;
    struct _typeobject *tp_prev;
    struct _typeobject *tp_next;
#endif
} PyTypeObject;

对象的创建

Python 创建对象由两种方法, 一种通过Python C API 来创建, 第二种是通过类型对象PyXX_Type来创建.
Python中的C API分成两类, 一类称为泛型的API,诸如PyObject_***的形式. 比如PyObject_Print

PyObject* intObj = PyObject = PyObject_New(PyObject, &PyInt_Type)