@@ -8,7 +8,7 @@ set是无序且不重复的集合,是可变的,通常用来从列表中删
88
99` 源文件: ` [ include/setobject.h] ( https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L26 )
1010
11- ```
11+ ``` c
1212typedef struct {
1313 PyObject *key;
1414 Py_hash_t hash; /* Cached hash code of the key */
@@ -19,8 +19,7 @@ key就是保存的数据,hash就是保存的数据的hash,便于查找,set
1919
2020` 源文件: ` [ include/setobject.h] ( https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L42 )
2121
22- ```
23-
22+ ``` c
2423typedef struct {
2524 PyObject_HEAD
2625
@@ -39,7 +38,7 @@ typedef struct {
3938 * runtime null-tests.
4039 */
4140 setentry *table; // 保存数据的数组数组指针
42- Py_hash_t hash; /* Only used by frozenset objects */
41+ Py_hash_t hash; /* Only used by frozenset objects */
4342 Py_ssize_t finger; /* Search finger for pop() */
4443
4544 setentry smalltable[PySet_MINSIZE]; // 保存数据的数组 默认初始化为8个元素,通过table指向
@@ -55,14 +54,13 @@ typedef struct {
5554
5655示例脚本如下:
5756
58- ```
57+ ``` python
5958set_a = {1 ,2 }
6059set_a.add(3 )
6160set_a.add(4 )
6261set_a.remove(1 )
6362set_a.update({3 ,})
6463set_a.union({1 ,5 })
65-
6664```
6765
6866通过python反汇编获取该脚本的字节码;
@@ -73,7 +71,7 @@ python -m dis set_test.py
7371
7472输出的字节码如下所示;
7573
76- ```
74+ ``` shell
7775 1 0 LOAD_CONST 0 (1)
7876 3 LOAD_CONST 1 (2)
7977 6 BUILD_SET 2
@@ -83,34 +81,34 @@ python -m dis set_test.py
8381 15 LOAD_ATTR 1 (add)
8482 18 LOAD_CONST 2 (3)
8583 21 CALL_FUNCTION 1
86- 24 POP_TOP
84+ 24 POP_TOP
8785
8886 3 25 LOAD_NAME 0 (set_a)
8987 28 LOAD_ATTR 1 (add)
9088 31 LOAD_CONST 3 (4)
9189 34 CALL_FUNCTION 1
92- 37 POP_TOP
90+ 37 POP_TOP
9391
9492 4 38 LOAD_NAME 0 (set_a)
9593 41 LOAD_ATTR 2 (remove)
9694 44 LOAD_CONST 0 (1)
9795 47 CALL_FUNCTION 1
98- 50 POP_TOP
96+ 50 POP_TOP
9997
10098 5 51 LOAD_NAME 0 (set_a)
10199 54 LOAD_ATTR 3 (update)
102100 57 LOAD_CONST 2 (3)
103101 60 BUILD_SET 1
104102 63 CALL_FUNCTION 1
105- 66 POP_TOP
103+ 66 POP_TOP
106104
107105 6 67 LOAD_NAME 0 (set_a)
108106 70 LOAD_ATTR 4 (union)
109107 73 LOAD_CONST 0 (1)
110108 76 LOAD_CONST 4 (5)
111109 79 BUILD_SET 2
112110 82 CALL_FUNCTION 1
113- 85 POP_TOP
111+ 85 POP_TOP
114112 86 LOAD_CONST 5 (None)
115113 89 RETURN_VALUE
116114```
@@ -124,29 +122,29 @@ python -m dis set_test.py
124122
125123` 源文件: ` [ Python/ceval.c] ( https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Python/ceval.c#L2318 )
126124
127- ```
125+ ``` c
128126// Python/ceval.c
129127
130- TARGET(BUILD_SET) {
131- PyObject *set = PySet_New(NULL); // 新建并初始化一个set
132- int err = 0;
133- int i;
134- if (set == NULL)
135- goto error;
136- for (i = oparg; i > 0; i--) { // 将传入初始化的参数传入
137- PyObject *item = PEEK(i);
138- if (err == 0)
139- err = PySet_Add(set, item); // 并依次对set进行添加操作
140- Py_DECREF(item);
141- }
142- STACKADJ(-oparg); // 移动弹栈
143- if (err != 0) {
144- Py_DECREF(set);
145- goto error;
146- }
147- PUSH(set); // 讲set压栈
148- DISPATCH(); // 执行下一条指令
128+ TARGET (BUILD_SET) {
129+ PyObject * set = PySet_New(NULL); // 新建并初始化一个set
130+ int err = 0;
131+ int i;
132+ if (set == NULL)
133+ goto error;
134+ for (i = oparg; i > 0; i--) { // 将传入初始化的参数传入
135+ PyObject * item = PEEK(i);
136+ if (err == 0)
137+ err = PySet_Add(set, item); // 并依次对set进行添加操作
138+ Py_DECREF(item);
149139 }
140+ STACKADJ(-oparg); // 移动弹栈
141+ if (err != 0) {
142+ Py_DECREF(set);
143+ goto error;
144+ }
145+ PUSH(set); // 讲set压栈
146+ DISPATCH(); // 执行下一条指令
147+ }
150148
151149```
152150
@@ -155,7 +153,7 @@ python -m dis set_test.py
155153`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2286)
156154
157155
158- ```
156+ ```c
159157PyObject *
160158PySet_New(PyObject *iterable)
161159{
@@ -201,7 +199,7 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
201199
202200` 源文件: ` [ Objects/setobject.c] ( https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2338 )
203201
204- ```
202+ ``` c
205203
206204int
207205PySet_Add (PyObject * anyset, PyObject * key)
@@ -219,7 +217,7 @@ PySet_Add(PyObject *anyset, PyObject *key)
219217
220218`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L419)
221219
222- ```
220+ ```c
223221static int
224222set_add_key(PySetObject *so, PyObject *key)
225223{
@@ -239,7 +237,7 @@ set_add_key(PySetObject *so, PyObject *key)
239237
240238` 源文件: ` [ Objects/setobject.c] ( https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L136 )
241239
242- ```
240+ ``` c
243241
244242static int
245243set_add_entry (PySetObject * so, PyObject * key, Py_hash_t hash)
@@ -301,7 +299,7 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
301299 if (i + LINEAR_PROBES <= mask) { // 检查当前索引值加上 9小于当前mask
302300 for (j = 0 ; j < LINEAR_PROBES ; j++) { // 循环9次
303301 entry++; // 向下一个位置
304- if (entry->hash == 0 && entry->key == NULL) // 如果找到当前hash为空或者key为空的则跳转到found_unused_or_dummy处执行
302+ if (entry->hash == 0 && entry->key == NULL) // 如果找到当前hash为空或者key为空的则跳转到found_unused_or_dummy处执行
305303 goto found_unused_or_dummy;
306304 if (entry->hash == hash) { // 如果找到的hash值相同
307305 PyObject *startkey = entry->key; // 获取该值
@@ -368,19 +366,19 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
368366
369367插入的概述如下,默认s初始化为空;
370368
371- ```
369+ ```python
372370s.add(1) // index = 1 & 7 = 1
373371```
374372
375373![ 插入1] ( ./set_insert_one.png )
376374
377- ```
375+ ``` python
378376s.add(2 ) // index = 2 & 7 = 2
379377```
380378
381379![ 插入2] ( ./set_insert_two.png )
382380
383- ```
381+ ``` python
384382s.add(7 ) // index = 9 & 7 = 1
385383```
386384
@@ -394,7 +392,7 @@ set的删除操作主要集中在set_remove()函数上,如下示例;
394392
395393` 源文件: ` [ Objects/setobject.c] ( https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L1921 )
396394
397- ```
395+ ``` c
398396
399397static PyObject *
400398set_remove (PySetObject * so, PyObject * key)
@@ -428,7 +426,7 @@ set_remove(PySetObject *so, PyObject *key)
428426
429427`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L447)
430428
431- ```
429+ ```c
432430
433431static int
434432set_discard_key(PySetObject *so, PyObject *key)
@@ -449,7 +447,7 @@ set_discard_key(PySetObject *so, PyObject *key)
449447
450448` 源文件: ` [ Objects/setobject.c] ( https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L400 )
451449
452- ```
450+ ``` c
453451
454452static int
455453set_discard_entry (PySetObject * so, PyObject * key, Py_hash_t hash)
@@ -479,7 +477,7 @@ set的resize主要依靠set_table_reseize函数来实现;
479477
480478`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L302)
481479
482- ```
480+ ```c
483481static int
484482set_table_resize(PySetObject *so, Py_ssize_t minused)
485483{
@@ -501,7 +499,7 @@ set_table_resize(PySetObject *so, Py_ssize_t minused)
501499 /* Get space for a new table. */
502500 oldtable = so->table; // 先获取旧的table
503501 assert(oldtable != NULL);
504- is_oldtable_malloced = oldtable != so->smalltable;
502+ is_oldtable_malloced = oldtable != so->smalltable;
505503
506504 if (newsize == PySet_MINSIZE) { // 如果获取的新大小与PySet_MINSIZE的大小相同
507505 /* A large table is shrinking, or we can't get any smaller. */
@@ -565,7 +563,7 @@ set_table_resize(PySetObject *so, Py_ssize_t minused)
565563
566564` 源文件: ` [ Objects/setobject.c] ( https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L267 )
567565
568- ```
566+ ``` c
569567static void
570568set_insert_clean (setentry * table, size_t mask, PyObject * key, Py_hash_t hash)
571569{
@@ -577,7 +575,7 @@ set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
577575 while (1) {
578576 entry = &table[i]; // 获取当前entry
579577 if (entry->key == NULL) // 如果为空则跳转值found_null设置key与hash
580- goto found_null;
578+ goto found_null;
581579 if (i + LINEAR_PROBES <= mask) { // 如果没有找到空值则通过该索引偏移9位去查找空余位置
582580 for (j = 0; j < LINEAR_PROBES; j++) {
583581 entry++;
0 commit comments