Object对象
文件位置:
\cpython-main\include\object.h
\cpython-main\Objects\object.c
以下是出自源码中的注释:
1、对象是分配在堆上的结构。对象的使用适用特殊规则,以确保它们被正确地垃圾回收。对象永远不会静态分配或在栈上分配;只能通过特殊的宏和函数访问它们。Type对象是这条规则的例外;标准类型由静态初始化的类型对象表示,尽管Python 2.2的类型/类统一工作也使堆分配类型对象成为可能。
2、对象的“引用计数”在复制或删除指向该对象的指针时增加或减少;当引用计数当达到0时,就没有对该对象的引用了,它可以从堆中移除。
3、一个对象中有Type字段用来表示它代表什么挥着包含什么样的数据类型。type在创建时是固定的。type本身也是对象,所以type对象中包含一个指向自己的指针。
4、对象不会再内存中浮动。一旦被分配对象,它将保持相同的大小和地址。用于保存可变大小数据的对象可以包含一个指向一个可变大小部分的指针。并不是所有相同type的对象都有相同的大小,但是一旦被分配就不能再改变大小。这些限制使得对对象的引用可以仅仅是一个简单的指针,移动位置可能导致要更新所有的指针,而改变大小则需要移动它。
5、对象总是通过类型为“PyObject *”的指针访问。而PyObject知识一个包含应用计数器和类型的数据结构
PyObject定义
typedef struct _object {
_PyObject_HEAD_EXTRA
Py_ssize_t ob_refcnt;
PyTypeObject *ob_type;
} PyObject;
PyVarObject定义,对于大小可变对象的定义
typedef struct {
PyObject ob_base;
Py_ssize_t ob_size; /* Number of items in variable part */
} PyVarObject;
type对象定义于 _typeobject这一结构体中,等价于 PyTypeObject。【一些简单的变量解释本文写在了注释里,比较复杂会在后面解释】
struct _typeobject {
PyObject_VAR_HEAD //#define PyObject_VAR_HEAD PyVarObject ob_base;
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;
Py_ssize_t tp_vectorcall_offset;
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;//repr() 函数将对象转化为供解释器读取的形式。调__repr__(self)
/* 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 */
/* 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;
/* Iterators */
getiterfunc tp_iter;
iternextfunc tp_iternext;
/* Attribute descriptor and subclassing stuff */
struct PyMethodDef *tp_methods;
struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;
// Strong reference on a heap type, borrowed reference on a static type
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;
vectorcallfunc tp_vectorcall;
};
type中有很多函数指针:
destructor
:typedef void (*destructor)(PyObject *)
用于回收内存
PyNumberMethods是定义为如下的结构体:其中 binaryfunc是指所有有两个参数的函数指针, ternaryfunc是有三个参数的函数指针。具体定义如下:
typedef PyObject * (*unaryfunc)(PyObject *);
typedef PyObject * (*binaryfunc)(PyObject *, PyObject *);
typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
typedef int (*inquiry)(PyObject *);
typedef struct {
/* Number implementations must check *both*
arguments for proper type and implement the necessary conversions
in the slot functions themselves. */
binaryfunc nb_add;
binaryfunc nb_subtract;
binaryfunc nb_multiply;
binaryfunc nb_remainder;
binaryfunc nb_divmod;
ternaryfunc nb_power;
unaryfunc nb_negative;
unaryfunc nb_positive;
unaryfunc nb_absolute;
inquiry nb_bool;
unaryfunc nb_invert;
binaryfunc nb_lshift;
binaryfunc nb_rshift;
binaryfunc nb_and;
binaryfunc nb_xor;
binaryfunc nb_or;
unaryfunc nb_int;
void *nb_reserved; /* the slot formerly known as nb_long */
unaryfunc nb_float;
binaryfunc nb_inplace_add;//+=
binaryfunc nb_inplace_subtract;//-+
binaryfunc nb_inplace_multiply;//*=
binaryfunc nb_inplace_remainder;
ternaryfunc nb_inplace_power;
binaryfunc nb_inplace_lshift;
binaryfunc nb_inplace_rshift;
binaryfunc nb_inplace_and;
binaryfunc nb_inplace_xor;
binaryfunc nb_inplace_or;
binaryfunc nb_floor_divide;
binaryfunc nb_true_divide;
binaryfunc nb_inplace_floor_divide;
binaryfunc nb_inplace_true_divide;
unaryfunc nb_index;
binaryfunc nb_matrix_multiply;
binaryfunc nb_inplace_matrix_multiply;
} PyNumberMethods;
PySequenceMethods是关于顺序对象的操作,结构定义如下:
typedef struct {
lenfunc sq_length;
binaryfunc sq_concat;
ssizeargfunc sq_repeat;
ssizeargfunc sq_item;
void *was_sq_slice;
ssizeobjargproc sq_ass_item;
void *was_sq_ass_slice;
objobjproc sq_contains;
binaryfunc sq_inplace_concat;
ssizeargfunc sq_inplace_repeat;
} PySequenceMethods;
PySequenceMethods中函数指针的意义与之前类似,都是使用typedef定义的指针,lenfunc即返回为数值的函数:typedef Py_ssize_t (*lenfunc)(PyObject *);
,ssizeargfunc为typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t);
表示有一个参数传入,ssizessizeargfunc表示有两个参数传入。之后类似的函数指针定义不在赘述,可以根据名称自行猜测。