Python 对象基础


object

PyObject

在python中所有的一切都是对象,对象都有一些相同的内容,这些内容在PyObject中被定义,也就是说,PyObject中出现的内容都将出现在python对象的开始几个字节中,PyObject的定义如下

typedef struct _object {
    _PyObject_HEAD_EXTRA
    Py_ssize_t ob_refcnt;
    PyTypeObject *ob_type;
} PyObject;
  • 在PyObject中,_PyObject_HEAD_EXTRA是另外定义的宏,在_PyObject_HEAD_EXTRA中定义了一个前向指针和一个后向指针,python使用双向链表将堆中的活跃元素串联起来。

    #define _PyObject_HEAD_EXTRA            \
        struct _object *_ob_next;           \
        struct _object *_ob_prev;
    
  • ob_refcnt字段指引用计数,这与python内存回收机制有关。
  • ob_type是一个指向_typeobject的指针,由于使用了typedef创建了别名:typedef struct _typeobject PyTypeObject;,所以在此使用PyTypeObject定义ob_type。ob_type用于指明这个对象的类型

PyVarObject

由于python中存在定长变量与变长变量之分,即不同定长对象占用内存大小相同,不同变长对象占用内存大小可能不同,上述的PyObject不能解决变长变量的问题,故在python中定义了PyVarObject

typedef struct {
    PyObject ob_base;
    Py_ssize_t ob_size; /* Number of items in variable part */
} PyVarObject;
  • 变长对象开始几个字节也是PyObject中定义的内容,但多添加了一项ob_size,由注释可知,它代表着变长对象的元素个数。由于是PyObject定义的前几个字节,所以在python中我们可以使用PyObject * 引用所有的python对象。

_typeobject

在PyObject中我们定义了ob_type,由于这个对象指明了python对象的类型,所以这个对象应当保存了python对象的元信息,包括占用的内存空间大小等。其大致包含以下几个方面:

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 */
    ...
    /* Method suites for standard classes */
    ...
    /* More standard operations (here for binary compatibility) */
    ...
    /* Functions to access object as input/output buffer */
    ...
    /* Flags to define presence of optional/expanded features */
    ...
    /* Documentation string */
    ...
    /* Assigned meaning in release 2.0 */
    /* call function for all accessible objects */
    ...
    /* delete references to contained objects */
    ...
    /* Assigned meaning in release 2.1 */
    /* rich comparisons */
    ...
    /* weak reference enabler */
    ...
    /* Iterators */
    ...
    /* Attribute descriptor and subclassing stuff */
    ...
    // Strong reference on a heap type, borrowed reference on a static type
    ...
    /* Type attribute cache version tag. Added in version 2.6 */
    ...
};
  • 类型名
  • 创建对象时应当预分配的空间大小
  • 与此对象相关的操作信息,比如一些函数指针,这些函数指针最后会指向某个函数或者指向null,这些指针将决定这个对象的行为。
  • 类型的类型

PyType_Type

我们发现_typeobject开头是PyVarObject,那么_typeobject对象内部也会有ob_type字段,其中ob_type字段就指向PyType_Type,即对象类型的类型。对象类型的类型这个对象是由PyTypeObject定义的,也就是_typeobject定义的(因为我们使用了宏定义typedef struct _typeobject PyTypeObject;,)

PyTypeObject PyType_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "type",                                     /* tp_name */
    sizeof(PyHeapTypeObject),                   /* tp_basicsize */
    sizeof(PyMemberDef),                        /* tp_itemsize */
    ...
};
  • PyVarObject_HEAD_INIT是定义初始化宏函数,在object.h中定义

    #define PyObject_HEAD_INIT(type)        \
        { _PyObject_EXTRA_INIT              \
        1, type },
    
    #define PyVarObject_HEAD_INIT(type, size)       \
        { PyObject_HEAD_INIT(type) size },
  • 我们发现PyType_Type对象的类型被指向了自身。所有的python对象最后都会指向PyType_Type
  • 我们可以在python中观察到

    >>> num = 1
    >>> num.__class__
    <type 'int'>
    >>> num.__class__.__class__
    <type 'type'>
    >>> num.__class__.__class__.__class__
    <type 'type'>
    >>> num.__class__.__class__ is type
    True
    >>> 

声明:Hello World|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - Python 对象基础


我的朋友,理论是灰色的,而生活之树是常青的!