说我有一个函数function
和一个类obj
的对象Class
。我有以下错误:
>>> func(**obj)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: func() argument after ** must be a mapping, not Class
因此,我的问题是:什么是映射?是否是dict
的所有映射子类?还是有__getitem__
必须实现的方法列表(例如__iter__
,Class
,...)被视为映射?
答案 0 :(得分:4)
根据Python docs:
一个支持任意键查找并实现Mapping或MutableMapping抽象基类中指定的方法的容器对象。 示例包括:
- dict
- collections.defaultdict
- collections.OrderedDict
- collections.Counter。
如果该类实现了mapping中的所有方法,则该类为Mapping / MutableMapping。
如果您将创建Mapping / MutableMapping派生类并实现所有这些,则将获得一个作为映射的类。
答案 1 :(得分:3)
here将术语“映射”描述为:
一个支持任意键查找和实现的容器对象
Mapping
或MutableMapping
抽象库中指定的方法 类。示例包括dict
,collections.defaultdict
,collections.OrderedDict
和collections.Counter
。
子类collections.abc.Mapping
的要求在其文档字符串中进行了描述:
"""A Mapping is a generic container for associating key/value pairs. This class provides concrete generic implementations of all methods except for __getitem__, __iter__, and __len__. """
因此,您可以通过子类化collections.abc.Mapping
并实现三种方法来定义新的映射类型:__len__
,__getitem__
和__iter__
。
>>> from collections.abc import Mapping
>>> def func(**kwargs):
... print(kwargs)
...
>>> class MyMapping(Mapping):
... def __len__(self):
... return 1
... def __getitem__(self, k):
... return 'bananas'
... def __iter__(self):
... return iter(['custard'])
...
>>> func(**MyMapping())
{'custard': 'bananas'}