1

刚刚在 dict "type" 子类化时遇到了问题。我确实重写了 __iter__ 方法,并预计它会影响其他方法,如 iterkeys、keys 等,因为我相信他们调用 __iter__ 方法来获取值,但似乎它们是独立实现的,我必须重写所有这些方法。

这是他们不使用其他方法并单独检索值的错误或意图吗?

我没有在标准 Python 文档描述中找到标准类的方法之间的调用依赖关系。对于子类化工作和定向需要哪些方法来覆盖正确的行为,这将很方便。是否有一些关于 python 基类型/类内部的补充文档?

4

4 回答 4

5

子类MappingMuteableMapping来自集合模块而不是,dict您可以免费获得所有这些方法。

这是一个最小映射的示例以及您免费获得的一些方法:

import collections
class MinimalMapping(collections.Mapping):
    def __init__(self, *items ):
        self.elements = dict(items)
    def __getitem__(self, key):
        return self.elements[key]
    def __len__(self):
        return len(self.elements)
    def __iter__(self):
        return iter(self.elements)

t = MinimalMapping()
print (t.iteritems, t.keys, t.itervalues, t.get)

要对任何内置容器进行子类化,您应该始终使用 collections 模块中的适当基类。

于 2010-10-29T16:15:18.967 回答
2

如果文档中未指定,则它是特定于实现的。CPython 可能重用该iter方法来实现的其他实现iterkeys和其他实现。我不会认为这是一个错误,而只是为实现者提供了一点自由。

我怀疑独立实现这些方法存在性能因素,尤其是字典在 Python 中如此广泛使用。

所以基本上,你应该实现它们。

于 2010-10-29T16:14:07.350 回答
1

你知道这句话:“你知道当你假设时会发生什么。” :-)

他们没有正式记录这些东西,因为他们可能决定在未来改变它。您可能找到的任何非官方文档都只会记录一个 Python 实现的当前行为,并且依赖它会导致您的代码非常非常脆弱。

当有特殊方法的官方文档时,它倾向于描述解释器相对于您自己的类的行为,例如使用__len__()when__nonzero__()没有实现,或者只需要__lt()__排序。

由于 Python 使用鸭子类型,您通常实际上不需要从内置类继承来使您自己的类表现得像一个。因此,您可能会重新考虑子类化dict是否真的是您想要做的。您可能会选择不同的类,例如collections模块中的某些东西,或者封装而不是继承。(UserString该类使用封装。)或者从头开始。

于 2010-10-29T16:19:12.480 回答
0

而不是 subclassing dict,您可以创建自己的类,该类具有您想要的属性,而不会带来太多麻烦。这是一篇博客文章,其中包含如何执行此操作的示例。其中的__str__()方法不是最好的,但这很容易纠正,其余的提供您寻求的功能。

于 2010-10-29T19:15:46.793 回答