是否有一个Python库用于带有回调函数的字典衍生物?

时间:2017-03-09 06:19:38

标签: python python-3.x dictionary

是否有一个Python库,它具有稳定的数据结构,用于具有回调函数的字典衍生物(或collections.MutableMapping的衍生物)?我的意思是'回调函数'在字典设置或获取项目时被调用。以下是我为此目的实施的内容。

from collections import MutableMapping

class TriggerDict(MutableMapping):

    def __init__(self, *args, **kwargs):
        self._dict = dict()
        self._triggers_set = dict()
        self._triggers_get = dict()
        super().__init__(*args, **kwargs)

    def __getitem__(self, key):
        return self.get(key)

    def __setitem__(self, key, value):
        self.set(key, value)

    def __delitem__(self, key):
        del self._dict[key]

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

    def __len__(self):
        return len(self._dict)

    def __str__(self):
        return str(self._dict)

    def __repr__(self):
        return repr(self._dict)

    def keys(self):
        return self._dict.keys()

    def values(self):
        return self._dict.values()

    def set_trigger(self, key, func, when='set'):
        if when == 'set':
            self._triggers_set[key] = func
        elif when == 'get':
            self._triggers_get[key] = func
        else:
            ValueError("You should choose 'set' or 'get' "
                       "for the timing of trigger, not '%s.'"%(when))

    def set(self, key, value, trigger=True):
        if key not in self._triggers_set:
            self._dict[key] = value
            return

        if trigger:
            func = self._triggers_set[key]
            self._dict[key] = func(key, value)
        else:
            self._dict[key] = value

    def get(self, key, default=None, trigger=True):
        if key not in self._triggers_get:
            return self._dict.get(key, default)

        if trigger:
            func = self._triggers_get[key]
            value = self._dict.get(key, default)
            return func(key, value)
        else:
            return self._dict.get(key, default)


def say_hello(key, value):
    print("Hello! %s"%(value))
    return value

def say_thanks(key, value):
    print("Thanks! %s"%(value))
    return value

if __name__ == '__main__':

    td = TriggerDict()
    td.set_trigger('GREETING', say_hello, when='set')
    td.set_trigger('GREETING', say_thanks, when='get')

    td['GREETING'] = 'Daewon'
    td['GREETING']

def say_thanks(key, value):
    print("Thanks! %s"%(value))
    return value

td = TriggerDict()
td.set_trigger('GREETING', say_hello, when='set')
td.set_trigger('GREETING', say_thanks, when='get')

td['GREETING'] = 'Daewon'
td['GREETING']

我根据VPfB的评论重构了上述代码如下。

class TriggerDict(UserDict):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._triggers_set = dict()
        self._triggers_get = dict()

    def __setitem__(self, key, value):
        self.set(key, value)

    def __getitem__(self, key):
        return self.get(key)

    def set_trigger(self, key, func, when='set'):
        if when == 'set':
            self._triggers_set[key] = func
        elif when == 'get':
            self._triggers_get[key] = func
        else:
            ValueError("You should choose 'set' or 'get' "
                       "for the timing of trigger, not '%s.'"%(when))

    def set(self, key, value, trigger=True):
        if key not in self._triggers_set:
            self.data[key] = value
            return

        if trigger:
            func = self._triggers_set[key]
            self.data[key] = func(key, value)
        else:
            self.data[key] = value

    def get(self, key, default=None, trigger=True):
        if key not in self._triggers_get:
            return self.data.get(key, default)

        if trigger:
            func = self._triggers_get[key]
            value = self.data.get(key, default)
            return func(key, value)
        else:
            return self.data.get(key, default)

0 个答案:

没有答案