什么是映射对象,根据dict类型?

wim*_*wim 12 python mapping dictionary

文档列出了创建dict实例的3种方法:

class dict(**kwarg)
class dict(mapping, **kwarg)
class dict(iterable, **kwarg)
Run Code Online (Sandbox Code Playgroud)

这里的映射究竟是什么?dict(mapping)工作所需的最小接口是什么?

Rob*_*obᵩ 13

CPython的源代码,这个评论:

/* We accept for the argument either a concrete dictionary object,
 * or an abstract "mapping" object.  For the former, we can do
 * things quite efficiently.  For the latter, we only require that
 * PyMapping_Keys() and PyObject_GetItem() be supported.
 */
Run Code Online (Sandbox Code Playgroud)

因此,"dict(映射)工作所需的最小接口"似乎是.keys().__getitem__().

示例程序:

class M:
    def keys(self):
        return [1,2,3]
    def __getitem__(self, x):
        return x*2

m = M()

d = dict(m)

assert d == {1:2, 2:4, 3:6}
Run Code Online (Sandbox Code Playgroud)


Pet*_*per 5

词汇表将其定义为:

一个支持任意键查找并实现MappingMutableMapping抽象基类中指定的方法的容器对象。实例包括dictcollections.defaultdictcollections.OrderedDictcollections.Counter

所以它看起来像的方法的最小单,以满足定义是__getitem____iter____len____contains__keysitemsvaluesget__eq__,和__ne__。尽管我敢打赌,dict构造函数实际上并不需要所有这些。


Mar*_*ler 2

像往常一样,请随意仔细阅读代码:)

那么,让我们进入Include/dictobject.h

132 /* PyDict_Merge updates/merges from a mapping object (an object that
133    supports PyMapping_Keys() and PyObject_GetItem()).  If override is true,
134    the last occurrence of a key wins, else the first.  The Python
135    dict.update(other) is equivalent to PyDict_Merge(dict, other, 1).
136 */
Run Code Online (Sandbox Code Playgroud)

所以我们正在寻找具有PyMapping_Keys和 的东西PyObject_GetItem。因为我们很懒,所以我们只是使用 python 文档中的搜索框并找到映射协议。因此,如果您的 CPython PyObject 遵循该协议,那么您就可以开始了。