擅长:python、mysql、java
<p>如果您想要一个实际保存数据的自定义集合,则子类<em>dict</em>。如果要扩展接口(例如add methods),这一点尤其有用。</p>
<p>但是,任何内置方法都不会调用自定义的<code>__getitem__</code>/<code>__setitem__</code>。如果需要对这些对象进行完全控制,请创建一个自定义类来实现<code>collections.MutableMapping</code>抽象基类。</p>
<p>ABC没有提供存储实际数据的方法,只是提供了一个接口,其中包含一些方法的默认实现。但是,这些默认实现将调用自定义的<code>__getitem__</code>和<code>__setitem__</code>。必须使用内部<code>dict</code>来保存数据,并实现所有抽象方法:<code>__len__</code>、<code>__iter__</code>、<code>__getitem__</code>、<code>__setitem__</code>和<code>__delitem__</code>。</p>
<p>来自<code>collections</code>模块的类<code>UserDict</code>(在Python 2中,该模块也被称为<code>UserDict</code>)是内部<code>dict</code>的包装器,实现了<code>MutableMapping</code>ABC。如果要自定义<code>dict</code>的行为,则此实现可能是一个起点。</p>
<p>总而言之:</p>
<ul>
<li><strong>可变映射</strong>定义接口。将其子类化以创建类似于<code>dict</code>的对象。完全取决于你是否以及如何存储数据。</li>
<li><strong>UserDict</strong>是使用内部“real”<code>dict</code>作为存储的<code>MutableMapping</code>的实现。如果希望使用类似dict的存储集合,但重写由<code>dict</code>公开的某些方法,这可能是一个很好的起点。但请确保阅读代码以了解基本方法是如何实现的,以便在重写方法时保持一致。</li>
<li><strong>dict是“真实的事物”。如果您想扩展接口,可以将其子类化。重写方法以执行自定义操作可能会很危险,因为通常有多种访问数据的方法,而且最终可能会出现不一致的API。</li>
</ul>