python:重载**字典解包

Hun*_*phu 1 python dictionary overloading

我希望能够从类似字典的类中解压一个对象。

当前的: f(**m.to_dict())

首选 f(**m)

如果存在的话,这将起作用starstarprepare

class M:
    #... __getitem__, __setitem__
    def __starstarprepare__(self):
        md = self.to_dict()
        return md
Run Code Online (Sandbox Code Playgroud)

che*_*ner 5

**适用于任何映射类型。创建M映射类型的一种方法是子类化collections.abc.Mapping并实现__getitem__, __iter__, 和__len__

from collections.abc import Mapping

class M(Mapping):
    def __init__(self):
        self.a = 3
        self.b = 5

    def __getitem__(self, key):
        return getattr(self, key)

    def __iter__(self):
        yield 'a'
        yield 'b'

    def __len__(self):
        return 2


def foo(**kwargs):
    for k, v in kwargs.items():
        print(k, v)


m = M()
foo(**m)
Run Code Online (Sandbox Code Playgroud)

如果您已经有一个to_dict方法,则所有三个魔术方法都可以是相应dict方法的包装器。

class M(Mapping):
    def __init__(self):
        self.a = 3
        self.b = 5

    def to_dict(self):
        return {'a': self.a, 'b': self.b}

    def __getitem__(self, key):
        return self.to_dict()[key]

    def __iter__(self):
        return iter(self.to_dict())

    def __len__(self):
        return len(self.to_dict())
Run Code Online (Sandbox Code Playgroud)

  • 当然,如果你希望“M”成为“dict”。但这掩盖了这样一个事实:“**”不需要“dict”(或“dict”的子类)。`dict` 的唯一特殊之处在于它是 Python 中唯一的“内置”映射类型。 (2认同)