1 整数对象PyIntObject
整数对象是固定大小的Python对象,内部只有一个ob_ival保存实际的整数值。
typedef struct {
PyObject_HEAD
long ob_ival;
} PyIntObject;
2 字符串对象PyStringObject
Python的字符串对象是一个不可变对象,任何改变字符串字面值的操作都是重新创建一个新的字符串。
字符串对象在Python中用PyStringObject表示,扩展定义后如下:
typedef struct {
Py_ssize_t ob_refcnt;//引用计数
struct _typeobject*ob_type; //类型指针
Py_ssize_t ob_size;//字符串的长度,不计算C语言中的结尾NULL
long ob_shash;// 字符串的hash值,没有计算则为-1int ob_sstate;//字符串对象的状态: 是否interned等
char ob_sval[1]; //保存字符串的内存,默认先分配1个字符,用来保存额外的末尾NULL值/*Invariants:* ob_sval contains space for 'ob_size+1'elements.* ob_sval[ob_size] ==0.* ob_shash is the hash of the string or -1 if notcomputed yet.* ob_sstate != 0 iff the string object is in stringobject.c's
* 'interned' dictionary; inthis case the two references* from 'interned' to this object are *not counted* inob_refcnt.*/} PyStringObject;
3 列表对象PyListObject;
typedef struct {
PyObject_VAR_HEAD#ob_item是用来保存元素的指针数组
PyObject **ob_item;#allocated是ob_item预先分配的内存总容量
Py_ssize_t allocated;
} PyListObject;
4 字典对象PyDictObject
在Python中,字典是通过哈希表实现的。也就是说,字典是一个数组,而数组的索引是键经过哈希函数处理后得到的。哈希函数的目的是使键均匀地分布在数组中。由于不同的键可能具有相同的哈希值,即可能出现冲突,高级的哈希函数能够使冲突数目最小化。
以下基于C语言的数据结构用于存储字典的键/值对(也称作 entry),存储内容有哈希值,键和值。PyObject 是 Python 对象的一个基类。
typedef struct {
Py_ssize_t me_hash;
PyObject*me_key;
PyObject*me_value
} PyDictEntry;
下面为字典对应的数据结构。其中,ma_fill为活动槽以及哑槽(dummy slot)的总数。当一个活动槽中的键/值对被删除后,该槽则被标记为哑槽。ma_used为活动槽的总数。ma_mask值为数组的长度减 1 ,用于计算槽的索引。ma_table为数组本身,ma_smalltable为长度为 8 的初始数组。
typedef struct _dictobject PyDictObject;
struct _dictobject {
PyObject_HEAD
Py_ssize_t ma_fill;
Py_ssize_t ma_used;
Py_ssize_t ma_mask;
PyDictEntry*ma_table;
PyDictEntry*(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash);
PyDictEntry ma_smalltable[PyDict_MINSIZE];
};
5 集合对象PySetObject
set与List对象相似,均为可变异构容器。但是其实现却和Dict类似,均为哈希表。具体的数据结构代码如下。
typedef struct {
long hash;/* cached hash code for the entry key */PyObject*key;
} setentry;/*This data structureis shared by set andfrozenset objects.*/typedef struct _setobject PySetObject;
struct _setobject {
PyObject_HEAD
Py_ssize_t fill;/* #Active + # Dummy */
Py_ssize_t used; /* #Active */
/* The table contains mask + 1 slots, and that's a power of 2.
* We store the mask instead of the size because the mask ismore*frequently needed.*/Py_ssize_t mask;/* table points to smalltable for small tables, elseto* additional malloc'ed memory. table is never NULL! This rule
* saves repeated runtime null-tests.*/setentry*table;
setentry*(*lookup)(PySetObject *so, PyObject *key, long hash);
setentry smalltable[PySet_MINSIZE];
long hash;/* only used by frozenset objects */PyObject*weakreflist; /* List of weak references */};
setentry是哈希表中的元素,记录插入元素的哈希值以及对应的Python对象。
PySetObject是哈希表的具体结构:
fill 被填充的键的个数,包括Active和dummy,稍后解释具体意思
used 被填充的键中有效的个数,即集合中的元素个数
mask 哈希表的长度的掩码,数值为容量值减一
table 存放元素的数组的指针
smalltable 默认的存放元素的数组
当元素较少时,所有元素只存放在smalltable数组中,此时table指向smalltable。当元素增多,会从新分配内存存放所有的元素,此时smalltable没有用,table指向新分配的内存。
参考: