Класс python, который действует как отображение для ** распаковки
Без подкласса dict, что класс должен считаться сопоставлением, чтобы его можно было передать методу с **
from abc import ABCMeta
class uobj:
__metaclass__ = ABCMeta
uobj.register(dict)
def f(**k): return k
o = uobj()
f(**o)
# outputs: f() argument after ** must be a mapping, not uobj
По крайней мере, до того момента, когда он выдает ошибки отсутствующей функциональности сопоставления, я могу начать реализовывать.
Я рассмотрел эмуляцию типов контейнеров, но просто определение магических методов не имеет никакого эффекта, и использование ABCMeta для переопределения и регистрации в виде dict проверяет утверждения как подкласс, но не имеет значения isinstance (o, dict). В идеале, я даже не хочу использовать ABCMeta.
Ответы
Ответ 1
Способы __getitem__()
и keys()
будут достаточны:
>>> 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'}
Ответ 2
Если вы пытаетесь создать сопоставление - не просто удовлетворяете требованиям для передачи функции - тогда вы действительно должны наследовать от collections.Mapping
. Как описано в документации, вам нужно просто реализовать:
__getitem__
__len__
__iter__
Mixin выполнит для вас все остальное: __contains__
, keys
, items
, values
, get
, __eq__
и __ne__
.