刚刚在dict“type”子类中遇到问题。我确实覆盖了__iter__方法,并期望它会影响其他方法,如iterkeys,keys等因为我认为他们调用__iter__方法来获取值,但似乎它们是独立实现的,我必须覆盖所有这些。
这是一个错误或意图,他们没有使用其他方法并单独检索值?
我没有在标准Python文档中找到标准类方法之间调用依赖关系的描述。对于子类化工作和方向来说,为了正确的行为需要覆盖哪些方法,这将是很方便的。是否有一些关于python基类型/类内部的补充文档?
答案 0 :(得分:5)
来自collections module而不是Mapping
的子类MuteableMapping
或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模块中的相应基类。
答案 1 :(得分:2)
如果文档中未指定,则特定于实现。 CPython可能会重复使用iter
方法实现iterkeys
和其他实现的其他实现。我不认为这是一个错误,但只是实现者的一点自由。
我怀疑在独立实现这些方法时存在性能因素,尤其是因为字典在Python中被广泛使用。
基本上,你应该实现它们。
答案 2 :(得分:1)
你知道这句话:“你知道当你假设会发生什么。” :-)
他们没有正式记录这些内容,因为他们可能决定在将来更改它。您可能找到的任何非官方文档都只是记录一个Python实现的当前行为,依赖它会导致您的代码非常非常脆弱。
当有特殊方法的官方文档时,它倾向于描述解释器相对于您自己的类的行为,例如在未实现__len__()
时使用__nonzero__()
,或仅需要{ {1}}用于排序。
由于Python使用duck typing,因此通常不需要从内置类继承来使自己的类像一个类。因此,您可能会重新考虑子类化__lt()__
是否真的是您想要做的。您可以选择不同的类,例如来自dict
模块的类,或者封装而不是继承。 (collections
类使用封装。)或者从头开始。
答案 3 :(得分:0)
而不是创建dict
的子类,您可以创建自己的类,使完全所需的属性,而不会有太多麻烦。这是一篇blog帖子,其中有一个如何执行此操作的示例。其中的__str__()
方法并不是最好的,但很容易纠正,其余方法提供了您所寻求的功能。