documentation列出了创建dict实例的3种方法:
class dict(**kwarg)
class dict(mapping, **kwarg)
class dict(iterable, **kwarg)
这里的映射究竟是什么? dict(mapping)
工作所需的最小接口是什么?
答案 0 :(得分:12)
来自the source code for 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.
*/
因此,“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}
答案 1 :(得分:4)
glossary将其定义为:
支持任意键查找和实现的容器对象 Mapping或MutableMapping抽象基础中指定的方法 类。示例包括
dict
,collections.defaultdict
,collections.OrderedDict
和collections.Counter
。
所以看起来满足定义的最小方法列表是__getitem__
,__iter__
,__len__
,__contains__
,keys
,{{1 },items
,values
,get
和__eq__
。虽然我打赌dict构造函数实际上并不需要所有这些。
答案 2 :(得分:3)
似乎只实施keys
和__getitem__
就足够了。
>>> class mydict:
... def keys(self):
... return 'xyz'
... def __getitem__(self, item):
... return 'potato'
...
>>> dict(mydict())
{'x': 'potato', 'y': 'potato', 'z': 'potato'}
答案 3 :(得分:0)
像往常一样,随意仔细阅读代码:)
所以,让我们进入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 */
因此,我们正在寻找拥有PyMapping_Keys
和PyObject_GetItem
的内容。因为我们很懒,所以我们只使用python文档中的搜索框并找到the mappings protocol。因此,如果你的CPython PyObject遵循该协议,你就可以了。
答案 4 :(得分:-1)
这是您问题的最佳答案:
https://docs.python.org/2/library/stdtypes.html#typesmapping
这是映射的最简单示例:{}
如果要创建自定义映射类型,可以从基础dict
继承并覆盖__getitem__
魔法(取决于您的需要)