Python 类,该类充当**解包的映射
如果不将dict子类化,那么类需要被视为映射,以便可以通过**将其传递给方法 至少在某种程度上,它会抛出缺少映射功能的错误,这样我就可以开始实现了 我回顾了模拟容器类型,但简单地定义magic方法没有效果,使用ABCMeta重写并注册为dict将断言验证为子类,但在instanceo,dict中失败。理想情况下,我甚至不想使用ABCMeta。使用u getitem_uuuuuuuuuuu和keys方法就足够了:Python 类,该类充当**解包的映射,python,class,mapping,argument-unpacking,Python,Class,Mapping,Argument Unpacking,如果不将dict子类化,那么类需要被视为映射,以便可以通过**将其传递给方法 至少在某种程度上,它会抛出缺少映射功能的错误,这样我就可以开始实现了 我回顾了模拟容器类型,但简单地定义magic方法没有效果,使用ABCMeta重写并注册为dict将断言验证为子类,但在instanceo,dict中失败。理想情况下,我甚至不想使用ABCMeta。使用u getitem_uuuuuuuuuuu和keys方法就足够了: >>> class D: def keys(sel
>>> class D:
def keys(self):
return ['a', 'b']
def __getitem__(self, key):
return key.upper()
>>> def f(**kwds):
print kwds
>>> f(**D())
{'a': 'A', 'b': 'B'}
如果您试图创建一个映射,而不仅仅是满足传递给函数的要求,那么您真的应该从collections.abc.Mapping继承。如中所述,您只需实现:
__getitem__
__len__
__iter__
Mixin将为您实现所有其他功能:uuu包含uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 尝试将非映射对象与**一起使用时,会出现以下错误:
TypeError: 'Foo' object is not a mapping
如果我们搜索CPython的错误源,我们可以找到:
关键部分是:
对于后者,我们只要求支持PyMapping_键和PyObject_GetItem
超出范围,但具有相关性和信息量,谢谢有用。这已经转移到collections.abc软件包中:@StuartBuckingham我感谢你的谦虚,但下次请随意编辑我的答案:啊,我不知道这是可能的。谢谢@Neig
TypeError: 'Foo' object is not a mapping
case TARGET(DICT_UPDATE): {
PyObject *update = POP();
PyObject *dict = PEEK(oparg);
if (PyDict_Update(dict, update) < 0) {
if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
_PyErr_Format(tstate, PyExc_TypeError,
"'%.200s' object is not a mapping",
Py_TYPE(update)->tp_name);
/* 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.
*/
if (a == NULL || !PyDict_Check(a) || b == NULL) {
PyErr_BadInternalCall();
return -1;