python object

核心理念”Everything is an object“(虽然我暂时没有找到这句话的出处)

Basic

  • identity: 内存中的唯一地址,获取函数id()
  • type: 类型,获取函数type()
  • value: 实际数据

Core

PyObject

CPython实现中的基础结构体,相当于所有Python类的基类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Include/pytypedefs.h
typedef struct _object PyObject;

// Include/object.h
struct _object {
_PyObject_HEAD_EXTRA // 继承自PyObject, 调试时额外启用双向链表
Py_ssize_t ob_refcnt; // 引用计数器
PyTypeObject *ob_type; // 类型对象指针
};

/* PyObject: 16byte or 32byte(trace)
+-------------------+
| _ob_next | pointer to PyObject: 64bit/8byte
+-------------------+
| _ob_prev | pointer to PyObject: 64bit/8byte
+-------------------+
| ob_refcnt | Py_ssize_t=signed integral type: 64bit/8byte
+-------------------+
| ob_type | pointer to PyTypeObject: 64bit/8byte
+-------------------+
*/

PyVarObject

可变长度对象的基类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Include/object.h
typedef struct {
PyObject ob_base;
Py_ssize_t ob_size;
} PyVarObject;
/* PyVarObject: 24byte or 40byte(trace)
+-------------------+
| ob_base | (trace header)
| | (trace header)
| |
| |
+-------------------+
| ob_size | Py_ssize_t=signed integral type: 64bit/8byte
+-------------------+
*/

Type

PyTypeObject

类型对象本身也是一种对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Include/pytypedefs.h
typedef struct _typeobject PyTypeObject;

// Include/cpython/object.h
struct _typeobject {
PyObject_VAR_HEAD // 继承自PyVarObject, 当子类对象为可变长度时关注PyVarObject.ob_size(元素个数)
const char *tp_name;
Py_ssize_t tp_basicsize, tp_itemsize;

/* typedef void (*destructor)(PyObject *self); */
destructor tp_dealloc; // 析构函数
// 在清除对象的成员字段之前, 调用 PyObject_GC_UnTrack(仅当支持GC时)
// 1.释放由 self 出发的所有引用; 2.释放内存缓冲区; 3.调用 tp_free, 对于非 subtypable 则是直接调用 deallocator;
// 调用 Py_DECREF 释放对 type 的引用(仅当对象的类型是存于堆时)
Py_ssize_t tp_vectorcall_offset; // 优化函数调用机制的偏移量
// 使用 vectorcall 协议代替 tp_call, 此时 tp_call 作为兜底方案
// 前置: 标志位 Py_TPFLAGS_HAVE_VECTORCALL 已设置;
// 此字段有演变历史: tp_print(输出到文件, Python2) -> tp_print(保留字段, before Python3.8)

/* !!deprecated, use tp_getattro&tp_setattro instead.
typedef PyObject *(*getattrfunc)(PyObject *self, char *attr);
typedef int (*setattrfunc)(PyObject *self, char *attr, PyObject *value);
*/
getattrfunc tp_getattr;
setattrfunc tp_setattr;

PyAsyncMethods *tp_as_async; // 异步操作支持
// 此字段有演变历史: tp_compare(对象比较, Python2) -> tp_reserved(保留字段, Python3)
reprfunc tp_repr;

PyNumberMethods *tp_as_number; // 数字操作支持
PySequenceMethods *tp_as_sequence; // 序列操作支持
PyMappingMethods *tp_as_mapping; // 映射操作支持

hashfunc tp_hash;
ternaryfunc tp_call;
reprfunc tp_str;
getattrofunc tp_getattro;
setattrofunc tp_setattro;

PyBufferProcs *tp_as_buffer; // 缓冲区操作支持

unsigned long tp_flags;

const char *tp_doc;

/*
// Include/object.h
typedef int (*traverseproc)(PyObject *self, visitproc visit, void *arg);
typedef int (*visitproc)(PyObject *object, void *arg);
*/
traverseproc tp_traverse; // 检测 reference cycles
// 前提: 标志位 Py_TPFLAGS_HAVE_GC 已设置;
// 典型遍历方法是 Py_VISIT(仅可对参与 reference cycles 的成员调用此方法, NULL 和 python string 等不可调用)

/*
// Include/object.h
typedef int (*inquiry)(PyObject *self);
*/
inquiry tp_clear; // 中断 reference cycles
// 前提: 标志位 Py_TPFLAGS_HAVE_GC 已设置;
// 删除对象实例对其成员的引用(要先把指针设置为NULL)

richcmpfunc tp_richcompare; // 比较操作支持

/* !still supported, use Py_TPFLAGS_MANAGED_WEAKREF in tp_flags instead. */
Py_ssize_t tp_weaklistoffset; // >0(当对象实例支持弱引用时, 且等于弱引用列表头的偏移量)

getiterfunc tp_iter;
iternextfunc tp_iternext;

PyMethodDef *tp_methods;
PyMemberDef *tp_members;
PyGetSetDef *tp_getset;

PyTypeObject *tp_base;
PyObject *tp_dict;
descrgetfunc tp_descr_get;
descrsetfunc tp_descr_set;

/* !still supported, use Py_TPFLAGS_MANAGED_DICT in tp_flags instead. */
Py_ssize_t tp_dictoffset; // 对象实例变量字典的偏移量
// 前提: 对象实例具有实例变量字典
// WRITEONLY
// 与 tp_dict 无关
// >0(以对象实例结构开头为偏移基底), <0(以对象实例结构结尾为偏移基底, 仅当对象实例包含变长属性时)

initproc tp_init;
/*
// Include/object.h
typedef PyObject *(*allocfunc)(PyTypeObject *cls, Py_ssize_t nitems);
*/
allocfunc tp_alloc; // 内存分配函数
// default=PyType_GenericAlloc(当属于动态 subtypes 时, 强制使用标准堆分配策略)
// recommend=PyType_GenericNew(当属于静态 subtypes 时)
newfunc tp_new;
/*
// Include/object.h
typedef void (*freefunc)(void *self);
*/
freefunc tp_free; // 对象实例释放函数, 底层的内存释放
// =PyObject_Del(当属于静态 subtypes 时)
inquiry tp_is_gc; // 被GC调用的函数
// 通常 GC 根据 Py_TPFLAGS_HAVE_GC 标志位判断对象是否可回收
// type 需要定义此函数来区分静态和动态(当 type 本身同时包含动态实例和不可回收的静态实例时)
PyObject *tp_bases;
PyObject *tp_mro;

/* !!!internal use only */
PyObject *tp_cache; // unused
PyObject *tp_subclasses; // 对子类的弱引用列表
PyObject *tp_weaklist; // (到 type 本身的)弱引用链头

/* !!deprecated use tp_finalize instead. */
destructor tp_del;

/* !!!internal use only */
unsigned int tp_version_tag; // 到方法缓存中的索引

destructor tp_finalize;
/*
typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames);
*/
vectorcallfunc tp_vectorcall; // 实现对 type.__call__ 的 vectorcall 优化
// default=NULL(兜底方案: __new__ 和 __init__)
};

对象协议&特殊方法

tp_name&name,module

通用格式: “[.[.]].

  • not be NULL
  • name==
    • 动态分配对象(例如用 type() 而非 class 语句创建的类)的 tp_name 只有
  • module==[.[.]]
    • default=‘main
1
2
3
4
5
6
cls=type('mycls',(object,),{'__module__':'test_module','x':100})
assert cls.__name__ == 'mycls'
assert cls.__module__ == 'test_module'

cls_default=type('mycls',(object,),{'x':21})
assert cls_default.__module__ == '__main__'

tp_basicsize&basicsize, tp_itemsize&itemsize

  • basicsize: 初始内存(结构体大小), 以字节为单位
  • itemsize: 单个元素内存占用大小, 以字节为单位
    变长对象(!=python可变对象)的这两个属性不可为空, 其实例大小=tp_basicsize+tp_itemsize*N(=ob_size)
    注意: PyLongObject 的 N=abs(ob_size), 即其 ob_size 同时还存储了符号位

tp_repr&repr

dafault=“<%type_name object at %memory_address>”

1
2
// Include/cpython/object.h
typedef PyObject *(*reprfunc)(PyObject *self); // repr也是PyObject对象

tp_hash&hash

返回值 -1 代表发生 error 以及抛出 exception
tp_hash=PyObject_HashNotImplemented() 等效于 __hash_=None

1
2
3
4
5
// Include/object.h
typedef Py_hash_t (*hashfunc)(PyObject *o);

// Include/pyport.h
typedef Py_ssize_t Py_hash_t;

tp_call&call

=NULL(当对象不可调用时)

tp_str&str

调用 str 类型的构造函数
被 print() 函数所使用, 兜底方案是 tp_repr

tp_getattro&getattr,getattribute

通常是 PyObject_GenericGetAttr()

1
2
// Include/object.h
typedef PyObject *(*getattrofunc)(PyObject *self, PyObject *attr);

tp_setattro&setattr,delattr

必须支持把 value 设置为 NULL 来删除对应属性
通常是 PyObject_GenericSetAttr()

1
2
// Include/object.h
typedef int (*setattrofunc)(PyObject *self, PyObject *attr, PyObject *value);

tp_flags&flags

bit mask, default=Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE

1
2
3
4
5
6
# 内置函数 (设置了 Py_TPFLAGS_METHOD_DESCRIPTOR)
len.__get__(obj) # 直接返回 len 函数本身

# 自定义函数 (未设置 Py_TPFLAGS_METHOD_DESCRIPTOR)
def my_func(self): pass
my_func.__get__(obj) # 返回一个新的 method 对象

tp_doc&doc

以 NULL 结尾的字符串, 代表此对象的 docstring

tp_iter&iter

返回对象的迭代器; 存在与否通常对应着对象实例是否可迭代(sequence 除外)

1
2
// Include/object.h
typedef PyObject *(*getiterfunc) (PyObject *);

tp_iternext&next

必须返回NULL(当迭代器耗尽时/当发生错误时); 不一定设置 StopInteration 异常

1
2
// Include/object.h
typedef PyObject *(*iternextfunc) (PyObject *);

tp_base&base

指向父类(单继承)
default=&PyBaseObject_Type

tp_dict&dict

类型本身的属性字典
PyType_Ready() 时被完善
default=NULL, 则PyType_Ready() 会直接赋值

tp_descr_get&get

1
2
// Include/object.h
typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *);

tp_descr_set&set,delete

1
2
// Include/object.h
typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *);

tp_init&init

tp_new 后被调用; 调用的是 tp_new 返回值的 tp_init; tp_int 不生效(当 tp_new 返回值不是预期 type 本身或其子类的实例时)

1
2
// Include/object.h
typedef int (*initproc)(PyObject *self, PyObject *args, PyObject *kwds);

tp_new&new

调用 subtype->tp_alloc 来为对象分配空间, 然后只执行绝对必要的初始化操作(其他可以忽略或重复的初始化操作应该被放到 tp_init)
经验: 所有初始化都在 tp_new(不可变类型)/tp_init(可变类型) 中进行

1
2
// Include/object.h
typedef PyObject *(*newfunc)(PyTypeObject *subtype, PyObject *args, PyObject *kwds);

tp_bases&bases

default=NULL(READONLY)
在 type 初始化时填充此属性
多重继承不适用于静态定义的类型, 将会只使用 bases 中的第一个

tp_mro&mro

default=NULL(READONLY)
在 type 初始化时填充此属性
方法解析顺序: type -> … -> object

tp_finalize&del

在实例的最终化时被调用(在对象被 tp_dealloc 释放之前), 也可能被 GC 调用(当实例处于 isolated reference cycles 时)
不会修改异常状态

协议集合

PyAsyncMethods *tp_as_async

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Include/cpython/object.h
typedef struct {
unaryfunc am_await; // __await__, 返回迭代器对象, 或者 NULL(当不是可迭代对象时)
unaryfunc am_aiter; // __aiter__, 返回异步迭代器对象, 或者 NULL(当对象未实现异步迭代协议时)
unaryfunc am_anext; // __anext__, 返回可迭代对象(即下一项), 或者 NULL(当迭代结束时)
sendfunc am_send; // __send__ , 将参数值发送到迭代器
} PyAsyncMethods;

// Include/object.h
typedef PyObject * (*unaryfunc)(PyObject *o); // 迭代器、异步迭代器、可迭代对象都是PyObject对象
typedef PySendResult (*sendfunc)(PyObject *iter, PyObject *value, PyObject **result);

/* PySendResult 在 Python 3.10 后才加入稳定 ABI
Py_LIMITED_API: 是否启用了受限(稳定) API 版本
Py_LIMITED_API+0: 强制转换为数值
0x030A0000: 03=Python3, 0A=10, 0000=reserved
*/
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000
typedef enum {
PYGEN_RETURN = 0, // return
PYGEN_ERROR = -1, // raised and exception
PYGEN_NEXT = 1, // yield
} PySendResult;
#endif

PyNumberMethods *tp_as_number

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// Include/cpython/object.h
typedef struct {
binaryfunc nb_add; // o1+o2
binaryfunc nb_subtract; // o1-o2
binaryfunc nb_multiply; // o1*o2
binaryfunc nb_remainder; // o1%o2
binaryfunc nb_divmod; // divmod(o1, o2)
ternaryfunc nb_power; // power(o1, o2, o3)=pow(base, exp) % mod
unaryfunc nb_negative; // -o1
unaryfunc nb_positive; // +o1
unaryfunc nb_absolute; // abs(o1)
inquiry nb_bool; // bool(o1)
unaryfunc nb_invert; // ~o1
binaryfunc nb_lshift; // o1<<o2
binaryfunc nb_rshift; // o1>>o2
binaryfunc nb_and; // o1&o2
binaryfunc nb_xor; // o1^o2
binaryfunc nb_or; // o1|o2
unaryfunc nb_int; // int(o1), 十进制
void *nb_reserved; // =NULL
// 此字段有演变历史: nb_long(Python2)
unaryfunc nb_float; // float(o1)
// o1=result
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; // o1//o2
binaryfunc nb_true_divide; // o1/o2
// o1=result
binaryfunc nb_inplace_floor_divide;
binaryfunc nb_inplace_true_divide;

unaryfunc nb_index; // int(o1) too, 返回的对象可作为索引(?)

binaryfunc nb_matrix_multiply; // o1@o2
// o1=result
binaryfunc nb_inplace_matrix_multiply;
} PyNumberMethods;

// Include/object.h
typedef PyObject * (*unaryfunc)(PyObject *o1); // 一元函数
typedef PyObject * (*binaryfunc)(PyObject *o1, PyObject *o2); // 二元函数
typedef PyObject * (*ternaryfunc)(PyObject *o1, PyObject *o2, PyObject *o3); // 三元函数
typedef int (*inquiry)(PyObject *self);

PySequenceMethods *tp_as_sequence

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Include/cpython/object.h
typedef struct {
lenfunc sq_length; // len()
binaryfunc sq_concat; // +
ssizeargfunc sq_repeat; // *
ssizeargfunc sq_item; // 针对负索引, 如果 sq_length!=NULL, 则调用其来计算得到正值
/* !!deprecated, use `sq_item` instead. */
void *was_sq_slice;
ssizeobjargproc sq_ass_item; // =NULL(当 item 不支持 assign 和 delete 时)
/* !!deprecated, use `sq_ass_item` instead. */
void *was_sq_ass_slice;
objobjproc sq_contains; // =NULL 时, 判断是否包含某个 item 会需要做遍历操作

binaryfunc sq_inplace_concat; // +=
ssizeargfunc sq_inplace_repeat; // *=
} PySequenceMethods;

// Include/object.h
typedef Py_ssize_t (*lenfunc)(PyObject *o);
typedef PyObject *(*ssizeargfunc)(PyObject *o, Py_ssize_t count);
typedef int(*ssizeobjargproc)(PyObject *o, Py_ssize_t i, PyObject *v);
typedef int (*objobjproc)(PyObject *o, PyObject *value);

PyMappingMethods *tp_as_mapping

1
2
3
4
5
6
7
8
9
// Include/cpython/object.h
typedef struct {
lenfunc mp_length; // len(), =NULL(当没有定义此属性时)
binaryfunc mp_subscript; // 获取 key 所对应的 value
objobjargproc mp_ass_subscript; // 赋值和删除操作
} PyMappingMethods;

// Include/object.h
typedef int(*objobjargproc)(PyObject *o, PyObject *key, PyObject *v);

PyBufferProcs *tp_as_buffer

常见场景: producer 和 consumer 通过共享内存来传递信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Include/cpython/object.h
typedef struct {
getbufferproc bf_getbuffer; // 缓冲区导出接口
releasebufferproc bf_releasebuffer; // 缓冲区释放接口
} PyBufferProcs;

typedef int (*getbufferproc)(PyObject *exporter, Py_buffer *view, int flags);
typedef void (*releasebufferproc)(PyObject *exporter, Py_buffer *view);

// Include/pybuffer.h
typedef struct {
void *buf;
PyObject *obj;
Py_ssize_t len;
Py_ssize_t itemsize;
int readonly;
int ndim;
char *format;
Py_ssize_t *shape;
Py_ssize_t *strides;
Py_ssize_t *suboffsets;
void *internal;
} Py_buffer;

richcmpfunc tp_richcompare

支持的比较: Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, Py_GE
返回结果: Py_True, Py_False, Py_NotImplemented(比较未定义), NULL(发生错误)

1
2
// Include/object.h
typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);

PyMethodDef *tp_methods

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Include/methodobject.h
struct PyMethodDef {
const char *ml_name;
PyCFunction ml_meth;
int ml_flags; // bitfield
// METH_VARARGS(通常)
// METH_KEYWORDS(支持关键字相关参数; 不能单独存在)
// METH_FASTCALL(快速调用约定, 仅支持位置参数, 需要参数数量 nargs)
// METH_METHOD(支持 defining_class, 例如可能是父类中定义的方法; 不能单独存在)
// METH_NOARGS(无参数)
// METH_O(单一参数对象)
// METH_CLASS(类方法, 类似于 `@classmethod` 装饰器)
// METH_STATIC(静态方法, 类似于 `@staticmethod` 装饰器)
// METH_COEXIST(允许方法覆盖同名定义, 而非忽略)
const char *ml_doc;
};

typedef PyObject *(*PyCFunction)(PyObject *self, PyObject *args);

PyMemberDef *tp_members

1
2
3
4
5
6
7
8
9
// Include/structmember.h
struct PyMemberDef {
const char *name;
int type; // T_ 宏之一
// T_SHORT(short), T_INT(int), T_LONG(long), T_FLOAT(float), T_DOUBLE(double), T_STRING(const char*, flags=READONLY), T_OBJECT(PyObject*, 当成员 =NULL 时返回 None, 可删除即 =NULL), T_OBJECT_EX(PyObject*, 当成员 =NULL 时抛出 AttributeError, 可删除即 =NULL), T_CHAR(char), T_BYTE(char), T_UBYTE(unsigned char), T_UINT(unsigned int), T_USHORT(unsigned short), T_ULONG(unsigned long), T_BOOL(T_BOOL), T_LONGLONG(long long), T_ULONGLONG(unsigned long long), T_PYSSIZET(Py_ssize_t)
Py_ssize_t offset; // 偏移量, 以字节为单位
int flags; // 0, READONLY
const char *doc;
};

PyGetSetDef *tp_getset

1
2
3
4
5
6
7
8
9
10
11
// Include/descrobject.h
struct PyGetSetDef {
const char *name;
getter get;
setter set; // 设置或删除属性
const char *doc;
void *closure; // 为 getter 和 setter 提供额外数据
};

typedef PyObject *(*getter)(PyObject *instance, void *closure);
typedef int (*setter)(PyObject *instance, PyObject *value, void *closure);

Common Types

PyLongObject

所有整数都借助任意长度的 PyLongObject 对象实现(采用PyVarObject头)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Include/cpython/longintrepr.h
struct _longobject {
PyObject_VAR_HEAD
digit ob_digit[1];
};
typedef uint32_t digit;

// Objects/longobject.c
PyTypeObject PyLong_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"int", // tp_name
offsetof(PyLongObject, ob_digit), // tp_basicsize
sizeof(digit), // tp_itemsize
0, // tp_dealloc
0, // tp_vectorcall_offset
0, // tp_getattr
0, // tp_setattr
0, // tp_as_async
long_to_decimal_string, // tp_repr
&long_as_number, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
(hashfunc)long_hash, // tp_hash
0, // tp_call
0, // tp_str
PyObject_GenericGetAttr, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LONG_SUBCLASS | _Py_TPFLAGS_MATCH_SELF, // tp_flags
long_doc, // tp_doc
0, // tp_traverse
0, // tp_clear
long_richcompare, // tp_richcompare
0, // tp_weaklistoffset
0, // tp_iter
0, // tp_iternext
long_methods, // tp_methods
0, // tp_members
long_getset, // tp_getset
0, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
0, // tp_init
0, // tp_alloc
long_new, // tp_new
PyObject_Free, // tp_free
};

static PyNumberMethods long_as_number = {
(binaryfunc)long_add, //nb_add
(binaryfunc)long_sub, //nb_subtract
(binaryfunc)long_mul, //nb_multiply
long_mod, //nb_remainder
long_divmod, //nb_divmod
long_pow, //nb_power
(unaryfunc)long_neg, //nb_negative
long_long, //tp_positive
(unaryfunc)long_abs, //tp_absolute
(inquiry)long_bool, //tp_bool
(unaryfunc)long_invert, //nb_invert
long_lshift, //nb_lshift
long_rshift, //nb_rshift
long_and, //nb_and
long_xor, //nb_xor
long_or, //nb_or
long_long, //nb_int
0, //nb_reserved
long_float, //nb_float
0, // nb_inplace_add/
0, // nb_inplace_subtract/
0, // nb_inplace_multiply/
0, // nb_inplace_remainder/
0, // nb_inplace_power/
0, // nb_inplace_lshift/
0, // nb_inplace_rshift/
0, // nb_inplace_and/
0, // nb_inplace_xor/
0, // nb_inplace_or/
long_div, // nb_floor_divide/
long_true_divide, // nb_true_divide/
0, // nb_inplace_floor_divide/
0, // nb_inplace_true_divide/
long_long, // nb_index/
};

PyFloatObject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Include/cpython/floatobject.h
typedef struct {
PyObject_HEAD
double ob_fval;
} PyFloatObject;

// Objects/floatobject.c
PyTypeObject PyFloat_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"float", // tp_name
sizeof(PyFloatObject), // tp_basicsize
0, // tp_itemsize
(destructor)float_dealloc, // tp_dealloc
0, // tp_vectorcall_offset
0, // tp_getattr
0, // tp_setattr
0, // tp_as_async
(reprfunc)float_repr, // tp_repr
&float_as_number, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
(hashfunc)float_hash, // tp_hash
0, // tp_call
0, // tp_str
PyObject_GenericGetAttr, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | _Py_TPFLAGS_MATCH_SELF, // tp_flags
float_new__doc__, // tp_doc
0, // tp_traverse
0, // tp_clear
float_richcompare, // tp_richcompare
0, // tp_weaklistoffset
0, // tp_iter
0, // tp_iternext
float_methods, // tp_methods
0, // tp_members
float_getset, // tp_getset
0, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
0, // tp_init
0, // tp_alloc
float_new, // tp_new
.tp_vectorcall = (vectorcallfunc)float_vectorcall,
};
static PyNumberMethods float_as_number = {
float_add, // nb_add
float_sub, // nb_subtract
float_mul, // nb_multiply
float_rem, // nb_remainder
float_divmod, // nb_divmod
float_pow, // nb_power
(unaryfunc)float_neg, // nb_negative
float_float, // nb_positive
(unaryfunc)float_abs, // nb_absolute
(inquiry)float_bool, // nb_bool
0, // nb_invert
0, // nb_lshift
0, // nb_rshift
0, // nb_and
0, // nb_xor
0, // nb_or
float___trunc___impl, // nb_int
0, // nb_reserved
float_float, // nb_float
0, // nb_inplace_add
0, // nb_inplace_subtract
0, // nb_inplace_multiply
0, // nb_inplace_remainder
0, // nb_inplace_power
0, // nb_inplace_lshift
0, // nb_inplace_rshift
0, // nb_inplace_and
0, // nb_inplace_xor
0, // nb_inplace_or
float_floor_div, // nb_floor_divide
float_div, // nb_true_divide
0, // nb_inplace_floor_divide
0, // nb_inplace_true_divide
};

PyUnicodeObject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Include/cpython/unicodeobject.h
typedef struct {
PyCompactUnicodeObject _base;
union {
void *any;
Py_UCS1 *latin1;
Py_UCS2 *ucs2;
Py_UCS4 *ucs4;
} data; // 规格最小的标准 Unicode 缓冲区
} PyUnicodeObject;

typedef struct {
PyASCIIObject _base;
Py_ssize_t utf8_length; // 不包含'\0'
char *utf8; // 以 NULL 结尾
Py_ssize_t wstr_length; // 代理位可能为 2
} PyCompactUnicodeObject;

typedef struct {
PyObject_HEAD
Py_ssize_t length;
Py_hash_t hash; // default=-1
struct {
unsigned int interned:2; // SSTATE_NOT_INTERNED(0), SSTATE_INTERNED_MORTAL(1), SSTATE_INTERNED_IMMORTAL(2)
unsigned int kind:3; // PyUnicode_WCHAR_KIND(0), PyUnicode_1BYTE_KIND(1), PyUnicode_2BYTE_KIND(2), PyUnicode_4BYTE_KIND(4)
unsigned int compact:1; // 紧凑与否
unsigned int ascii:1; // 仅包含 ASCII 字符
unsigned int ready:1;
unsigned int :24; // Padding
} state;
wchar_t *wstr;
} PyASCIIObject;

// Objects/unicodeobject.c
PyTypeObject PyUnicode_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"str", // tp_name
sizeof(PyUnicodeObject), // tp_basicsize
0, // tp_itemsize
(destructor)unicode_dealloc, // tp_dealloc
0, // tp_vectorcall_offset
0, // tp_getattr
0, // tp_setattr
0, // tp_as_async
unicode_repr, // tp_repr
&unicode_as_number, // tp_as_number
&unicode_as_sequence, // tp_as_sequence
&unicode_as_mapping, // tp_as_mapping
(hashfunc) unicode_hash, // tp_hash
0, // tp_call
(reprfunc) unicode_str, // tp_str
PyObject_GenericGetAttr, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_UNICODE_SUBCLASS | _Py_TPFLAGS_MATCH_SELF, // tp_flags
unicode_doc, // tp_doc
0, // tp_traverse
0, // tp_clear
PyUnicode_RichCompare, // tp_richcompare
0, // tp_weaklistoffset
unicode_iter, // tp_iter
0, // tp_iternext
unicode_methods, // tp_methods
0, // tp_members
0, // tp_getset
0, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
0, // tp_init
0, // tp_alloc
unicode_new, // tp_new
PyObject_Del, // tp_free
};

static PyNumberMethods unicode_as_number = {
0, // nb_add
0, // nb_subtract
0, // nb_multiply
unicode_mod, // nb_remainder
};

static PySequenceMethods unicode_as_sequence = {
(lenfunc) unicode_length, // sq_length
PyUnicode_Concat, // sq_concat
(ssizeargfunc) unicode_repeat, // sq_repeat
(ssizeargfunc) unicode_getitem, // sq_item
0, // sq_slice
0, // sq_ass_item
0, // sq_ass_slice
PyUnicode_Contains, // sq_contains
};

static PyMappingMethods unicode_as_mapping = {
(lenfunc)unicode_length, // mp_length
(binaryfunc)unicode_subscript, // mp_subscript
(objobjargproc)0, // mp_ass_subscript
};

PyListObject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// Include/cpython/listobject.h
typedef struct {
PyObject_VAR_HEAD
PyObject **ob_item; // ob_item[0] is list[0]
Py_ssize_t allocated; // 0 <= len(list)=ob_size <= allocated
} PyListObject;

// Objects/listobject.c
PyTypeObject PyList_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"list", // tp_name
sizeof(PyListObject), // tp_basicsize
0, // tp_itemsize
(destructor)list_dealloc, // tp_dealloc
0, // tp_vectorcall_offset
0, // tp_getattr
0, // tp_setattr
0, // tp_as_async
(reprfunc)list_repr, // tp_repr
0, // tp_as_number
&list_as_sequence, // tp_as_sequence
&list_as_mapping, // tp_as_mapping
PyObject_HashNotImplemented, // tp_hash
0, // tp_call
0, // tp_str
PyObject_GenericGetAttr, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS | _Py_TPFLAGS_MATCH_SELF | Py_TPFLAGS_SEQUENCE, // tp_flags
list___init____doc__, // tp_doc
(traverseproc)list_traverse, // tp_traverse
(inquiry)_list_clear, // tp_clear
list_richcompare, // tp_richcompare
0, // tp_weaklistoffset
list_iter, // tp_iter
0, // tp_iternext
list_methods, // tp_methods
0, // tp_members
0, // tp_getset
0, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
(initproc)list___init__, // tp_init
PyType_GenericAlloc, // tp_alloc
PyType_GenericNew, // tp_new
PyObject_GC_Del, // tp_free
.tp_vectorcall = list_vectorcall,
};

static PySequenceMethods list_as_sequence = {
(lenfunc)list_length, // sq_length
(binaryfunc)list_concat, // sq_concat
(ssizeargfunc)list_repeat, // sq_repeat
(ssizeargfunc)list_item, // sq_item
0, // sq_slice
(ssizeobjargproc)list_ass_item, // sq_ass_item
0, // sq_ass_slice
(objobjproc)list_contains, // sq_contains
(binaryfunc)list_inplace_concat, // sq_inplace_concat
(ssizeargfunc)list_inplace_repeat, // sq_inplace_repeat
};

static PyMappingMethods list_as_mapping = {
(lenfunc)list_length,
(binaryfunc)list_subscript,
(objobjargproc)list_ass_subscript
};

PyDictObject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Include/cpython/dictobject.h
typedef struct {
PyObject_HEAD
Py_ssize_t ma_used; // 字典里 item 数量
uint64_t ma_version_tag; // 全局唯一
PyDictKeysObject *ma_keys;
PyDictValues *ma_values;
} PyDictObject;

// Include/internal/pycore_dict.h
struct _dictkeysobject {
Py_ssize_t dk_refcnt;
uint8_t dk_log2_size; // 哈希表(dk_indices)大小, 必须为 2 的幂
uint8_t dk_log2_index_bytes; // 哈希表(dk_indices)大小, 字节数
uint8_t dk_kind;
uint32_t dk_version;
Py_ssize_t dk_usable;
Py_ssize_t dk_nentries;
char dk_indices[];
};

struct _dictvalues {
PyObject *values[1]; // [-1]=prefix size. [-2]=used size. size[-2-n...]=insertion order.
};

// Objects/dictobject.c

PyTypeObject PyDict_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"dict", // tp_name
sizeof(PyDictObject), // tp_basicsize
0, // tp_itemsize
(destructor)dict_dealloc, // tp_dealloc
0, // tp_vectorcall_offset
0, // tp_getattr
0, // tp_setattr
0, // tp_as_async
(reprfunc)dict_repr, // tp_repr
&dict_as_number, // tp_as_number
&dict_as_sequence, // tp_as_sequence
&dict_as_mapping, // tp_as_mapping
PyObject_HashNotImplemented, // tp_hash
0, // tp_call
0, // tp_str
PyObject_GenericGetAttr, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DICT_SUBCLASS | _Py_TPFLAGS_MATCH_SELF | Py_TPFLAGS_MAPPING, // tp_flags
dictionary_doc, // tp_doc
dict_traverse, // tp_traverse
dict_tp_clear, // tp_clear
dict_richcompare, // tp_richcompare
0, // tp_weaklistoffset
(getiterfunc)dict_iter, // tp_iter
0, // tp_iternext
mapp_methods, // tp_methods
0, // tp_members
0, // tp_getset
0, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
dict_init, // tp_init
_PyType_AllocNoTrack, // tp_alloc
dict_new, // tp_new
PyObject_GC_Del, // tp_free
.tp_vectorcall = dict_vectorcall,
};

static PyNumberMethods dict_as_number = {
.nb_or = dict_or,
.nb_inplace_or = dict_ior,
};

static PySequenceMethods dict_as_sequence = {
0, // sq_length
0, // sq_concat
0, // sq_repeat
0, // sq_item
0, // sq_slice
0, // sq_ass_item
0, // sq_ass_slice
PyDict_Contains, // sq_contains
0, // sq_inplace_concat
0, // sq_inplace_repeat
};

static PyMappingMethods dict_as_mapping = {
(lenfunc)dict_length, //mp_length
(binaryfunc)dict_subscript, //mp_subscript
(objobjargproc)dict_ass_sub, //mp_ass_subscript
};

PySliceObject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// Include/sliceobject.h
typedef struct {
PyObject_HEAD
PyObject *start, *stop, *step; // not NULL
} PySliceObject;

// Objects/sliceobject.c
PyTypeObject PySlice_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"slice", // tp_name
sizeof(PySliceObject), // tp_basicsize
0, // tp_itemsize
(destructor)slice_dealloc, // tp_dealloc
0, // tp_vectorcall_offset
0, // tp_getattr
0, // tp_setattr
0, // tp_as_async
(reprfunc)slice_repr, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
PyObject_HashNotImplemented, // tp_hash
0, // tp_call
0, // tp_str
PyObject_GenericGetAttr, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
slice_doc, // tp_doc
(traverseproc)slice_traverse, // tp_traverse
0, // tp_clear
slice_richcompare, // tp_richcompare
0, // tp_weaklistoffset
0, // tp_iter
0, // tp_iternext
slice_methods, // tp_methods
slice_members, // tp_members
0, // tp_getset
0, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
0, // tp_init
0, // tp_alloc
slice_new, // tp_new
};