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类:
- 类型名, tp_name, 主要是Python内部以及调试的时候使用
- 创建该类型对象时分配内存空间大小的信息, 即tp_basicsize和tp_itemsize;
- 与该类型对象相关联的操作信息
- 描述类型的累心信息
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)