[cpyhon源代码]dict对象原理学习

Posted muyiblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[cpyhon源代码]dict对象原理学习相关的知识,希望对你有一定的参考价值。

Cpython 2.7 分支中,dict 对象的源代码 lookdict 搜索算法

 

 1 static PyDictEntry *
 2 lookdict(PyDictObject *mp, PyObject *key, register long hash)
 3 {
 4     register size_t i;
 5     register size_t perturb;
 6     register PyDictEntry *freeslot;
 7     register size_t mask = (size_t)mp->ma_mask;
 8     PyDictEntry *ep0 = mp->ma_table;
 9     register PyDictEntry *ep;
10     register int cmp;
11     PyObject *startkey;
12 
13     i = (size_t)hash & mask;
14     ep = &ep0[i];
15     if (ep->me_key == NULL || ep->me_key == key) //【1】
16         return ep;
17 
18     if (ep->me_key == dummy)
19         freeslot = ep;
20     else {
21 //进到这里说明 ep->me-key !=NULL && ep->me_key!=key && ep->me_key==Active
22         if (ep->me_hash == hash) {
23             startkey = ep->me_key;
24             Py_INCREF(startkey);
25             cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); //[2]这里为啥要再比较一次?
26             Py_DECREF(startkey);
27             if (cmp < 0)
28                 return NULL;
29             if (ep0 == mp->ma_table && ep->me_key == startkey) {//[3]这里明显是相等的,为啥要再判断一次?
30                 if (cmp > 0)
31                     return ep;
32             }
33             else {
34                 /* The compare did major nasty stuff to the
35                  * dict:  start over.
36                  * XXX A clever adversary could prevent this
37                  * XXX from terminating.
38                  */
39                 return lookdict(mp, key, hash);
40             }
41         }
42         freeslot = NULL;
43     }

 

  

两个问题无法理解:

  1.1 dict 对象搜索算法中,进入【2】处已经说明了 ep->me_key!=key 这个条件成立,但是 【2】那里为啥要再次比较一次 me_key 和 key 呢?

百思不得其解!!!

      原因: 【1】处为两个指针做 == 比较,说明指针的内容相同,即指向的是同一对象

                  进入到流程【2】则说明两个对象指向不同的内存,但是在满足两个条件后也认为他们“相等”,从而返回对应的项目,条件如下:

                  一是 两个对象哈希值相等

                  二是 两个对象的值相等(比较算法由对象提供,通常是 __eq__方法)

     举例:dict[10000]=10,此时需要搜索 d[10000]对象的 entry 对象,搜索时 指向 10000 的Pyobject* 明显和之前 存入 dict[10000] 值时对应的

               Pyobject 指针不一致,此时 p(p->int(10000) me_key) != q(q->int(10000) key),因此不会进入流程 【1】

               但是 p,q同时满足规定的两个条件,即hash值和 ob_val 都一致,因此返回 p 处的 (key,value)entry

   

     1.2 [3]处 判断的条件明显是成立的(参见蓝色高亮部分),不理解为啥要重复判断一次,暂时想不通~

     

以上是关于[cpyhon源代码]dict对象原理学习的主要内容,如果未能解决你的问题,请参考以下文章

Python代码阅读(第19篇):合并多个字典

VSCode自定义代码片段12——JavaScript的Promise对象

VSCode自定义代码片段12——JavaScript的Promise对象

VSCode自定义代码片段——JS中的面向对象编程

VSCode自定义代码片段9——JS中的面向对象编程

IOS开发-OC学习-常用功能代码片段整理