【发布时间】:2017-04-01 17:09:42
【问题描述】:
documentation 列出了 3 种创建 dict 实例的方法:
class dict(**kwarg)
class dict(mapping, **kwarg)
class dict(iterable, **kwarg)
映射到底是什么? dict(mapping) 工作所需的最小接口是什么?
【问题讨论】:
标签: python dictionary mapping
documentation 列出了 3 种创建 dict 实例的方法:
class dict(**kwarg)
class dict(mapping, **kwarg)
class dict(iterable, **kwarg)
映射到底是什么? dict(mapping) 工作所需的最小接口是什么?
【问题讨论】:
标签: python dictionary mapping
来自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(mapping) 工作所需的最小接口”似乎是.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}
【讨论】:
glossary 将其定义为:
支持任意键查找和实现的容器对象 Mapping 或 MutableMapping 抽象基中指定的方法 类。示例包括
dict、collections.defaultdict、collections.OrderedDict和collections.Counter。
所以看起来满足定义的最小方法列表是__getitem__、__iter__、__len__、__contains__、keys、items、values、get、@ 987654340@ 和 __ne__。虽然我敢打赌 dict 构造函数实际上并不需要所有这些。
【讨论】:
似乎只实现keys 和__getitem__ 就足够了。
>>> class mydict:
... def keys(self):
... return 'xyz'
... def __getitem__(self, item):
... return 'potato'
...
>>> dict(mydict())
{'x': 'potato', 'y': 'potato', 'z': 'potato'}
【讨论】:
** 参数解包。
像往常一样,请随意阅读代码:)
那么,让我们进入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 遵循该协议,那么您就可以开始了。
【讨论】:
这是您问题的最佳答案:
https://docs.python.org/2/library/stdtypes.html#typesmapping
这是最简单的映射示例:{}
如果你想创建一个自定义映射类型,你可以从基础dict继承它并覆盖__getitem__魔术方法(这取决于你的需要)
【讨论】:
dictionaries 都是映射,但并非所有映射都是字典 - 这个问题是询问什么构成映射而不是举例。
dict,根本不是每个映射都必须是一个字典。
{} 不是最简单的映射示例。 {} 上面有各种各样的废话