How to properly subclass dict and override __getitem__ & __setitem__
我正在调试一些代码,我想知道何时访问特定的字典。实际上,它是一个类,子类
1 2 3 4 5 6 7 8 9 10 11 12 | class DictWatch(dict): def __init__(self, *args): dict.__init__(self, args) def __getitem__(self, key): val = dict.__getitem__(self, key) log.info("GET %s['%s'] = %s" % str(dict.get(self, 'name_label')), str(key), str(val))) return val def __setitem__(self, key, val): log.info("SET %s['%s'] = %s" % str(dict.get(self, 'name_label')), str(key), str(val))) dict.__setitem__(self, key, val) |
"
谢谢你的帮助!
子类化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class DictWatch(dict): def __init__(self, *args, **kwargs): self.update(*args, **kwargs) def __getitem__(self, key): val = dict.__getitem__(self, key) print 'GET', key return val def __setitem__(self, key, val): print 'SET', key, val dict.__setitem__(self, key, val) def __repr__(self): dictrepr = dict.__repr__(self) return '%s(%s)' % (type(self).__name__, dictrepr) def update(self, *args, **kwargs): print 'update', args, kwargs for k, v in dict(*args, **kwargs).iteritems(): self[k] = v |
你所做的应该是绝对有效的。我测试了您的类,除了日志语句中缺少左括号外,它还可以正常工作。我能想到的只有两件事。首先,日志语句的输出设置是否正确?您可能需要在脚本顶部放置一个
其次,
这不会真正改变结果(对于良好的日志阈值,应该是有效的):您的初始化应该是:
1 | def __init__(self,*args,**kwargs) : dict.__init__(self,*args,**kwargs) |
相反,因为如果使用dictwatch([(1,2),(2,3)]或dictwatch(a=1,b=2)调用方法,这将失败。
(或者,更好的是,不要为此定义构造函数)
考虑子类化
你要做的就是
1 2 3 | class BatchCollection(dict): def __init__(self, inpt={}): super(BatchCollection, self).__init__(inpt) |
我个人使用的示例用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ### EXAMPLE class BatchCollection(dict): def __init__(self, inpt={}): super(BatchCollection, self).__init__(inpt) def __setitem__(self, key, item): if (isinstance(key, tuple) and len(key) == 2 and isinstance(item, collections.Iterable)): # self.__dict__[key] = item super(BatchCollection, self).__setitem__(key, item) else: raise Exception( "Valid key should be a tuple (database_name, table_name)" "and value should be iterable") |
注:仅在python3中测试