web-dev-qa-db-ja.com

**開梱のマッピングとして機能するクラス

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を使いたくありません。

62
dskinner

__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'}
76

関数に渡すための要件を満たすだけでなく、マッピングを作成しようとしている場合は、実際にはcollections.Mappingから継承する必要があります。 documentation で説明されているように、次のものだけを実装する必要があります。

__getitem__
__len__
__iter__

Mixinは他のすべてを実装します:__contains__keysitemsvaluesget__eq__、および__ne__

22
Neil G