是否有一个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)