2010-08-02 94 views
8

我想实现一个类换行 - 不是子类 - python dict对象,以便当在后台存储中检测到更改时,我可以重新创建委托的dict对象。我打算在每次访问字典进行读取时检查后备存储器中的更改。如何包装python字典?

假设我要创建一个对象来执行此操作;我需要实施哪些方法?

回答

12

你也可以继承的ABC(抽象基类)collections.Mapping(或collections.MutableMapping如果您还想允许使用情况来改变模拟/包裹词典,例如,通过索引分配,pop等代码)。

如果这样做的话,因为我的文档指出,有些间接的暗示,你需要实现的方法是

__len__ 
__iter__ 
__getitem__ 

(对于Mapping) - 你应该实施

__contains__ 

因为通过委托给你包装它的字典可以做得比ABC不得不应用迭代方法快得多。

如果您需要提供一个MutableMapping,那么你还需要实现2种方法:

__setitem__ 
__delitem__  
+0

在python 3中,有没有办法“批量”转发所有这些方法,而无需为每个方法手动复制/粘贴几乎相同的代码?普通的'__getattr__'不起作用,因为在类而不是实例上查找了特殊的方法,并且该查找跳过了__getattr__。 – max 2016-11-11 23:42:01

1

我认为这取决于您所使用的方法。可能__getitem__,__setitem__,__iter____len__,因为大多数事情可以用这些方式来实现。但是你会想看看一些用例,特别是__iter__。事情是这样的:

for key in wrapped_dictionary: 
    do_something(wrapped_dictionary[key]) 

...将是缓慢的,如果你打在每个迭代的数据源,更何况,如果数据源是从下你变幻出它甚至可能没有工作。因此,您可能希望在那里抛出某种异常,并实施iteritems作为替代方法,在循环播放之前将所有键值对加载到一个批处理中。

Pythondocs有项目清单,您可以在其中查找方法和用例。

2

除了已经建议的内容之外,您可能还想看看UserDict

对于类似于dict的对象的示例,您可以阅读django的session implementation,特别是SessionBase类。

+0

正如所提供的文档链接所示,UserDict几乎被dict子类(自Python 2.2以来)和Alex Martelli(自Python 2.6以来)建议的ABC方法所取代。 – NeilenMarais 2014-11-28 14:12:14