刚刚在字典“类型”子类化中遇到了问题。我确实重写了 __iter__ 方法,并预计它会影响 iterkeys、keys 等其他方法,因为我相信它们调用 __iter__ 方法来获取值,但似乎它们是独立实现的,我必须重写所有这些方法。
这是一个错误还是他们不使用其他方法并单独检索值的意图?
我在标准Python文档中没有找到标准类方法之间调用依赖关系的描述。对于子类化工作和指导需要覆盖哪些方法才能实现正确的行为,这将很方便。是否有一些关于 python 基类型/类内部的补充文档?
just encountered a problem at dict "type" subclassing. I did override __iter__ method and expected it will affect other methods like iterkeys, keys etc. because I believed they call __iter__ method to get values but it seems they are implemented independently and I have to override all of them.
Is this a bug or intention they don't make use of other methods and retrieves values separately ?
I didn't find in the standard Python documentation description of calls dependency between methods of standard classes. It would be handy for sublassing work and for orientation what methods is required to override for proper behaviour. Is there some supplemental documentation about python base types/classes internals ?
发布评论
评论(4)
来自 Mapping 或
MuteableMapping
="nofollow">集合模块而不是dict
,您可以免费获得所有这些方法。以下是最小映射的示例以及您免费获得的一些方法:
要对任何内置容器进行子类化,您应该始终使用集合模块中适当的基类。
Subclass
Mapping
orMuteableMapping
from the collections module instead ofdict
and you get all those methods for free.Here is a example of a minimal mapping and some of the methods you get for free:
To subclass any of the builtin containers you should always use the appropriate baseclass from the collections module.
如果文档中未指定,则它是特定于实现的。 CPython 以外的实现可能会重用
iter
方法来实现iterkeys
等。我不认为这是一个错误,而只是实现者的一点自由。我怀疑独立实现这些方法存在性能因素,尤其是字典在 Python 中被广泛使用。
所以基本上,你应该实现它们。
If not specified in the documentation, it is implementation specific. Implementations other that CPython might re-use the
iter
method to implementiterkeys
and others. I would not consider this to be a bug, but simply a bit of freedom for the implementors.I suspect there is a performance factor in implementing the methods independently, especially as dictionaries are so widely used in Python.
So basically, you should implement them.
你知道这句话:“当你假设时,你就知道会发生什么。” :-)
他们没有正式记录这些内容,因为他们可能决定在将来更改它。您可能找到的任何非官方文档都只是记录了一个 Python 实现的当前行为,依赖它会导致您的代码非常非常脆弱。
当有特殊方法的官方文档时,它往往会描述解释器相对于您自己的类的行为,例如当
__nonzero__()
不存在时使用__len__()
t 已实现,或者只需要__lt()__
进行排序。由于 Python 使用鸭子类型,因此您通常不需要从内置类继承来使您自己的类表现得像一个类。因此,您可能会重新考虑子类化
dict
是否真的是您想要做的事情。您可以选择不同的类,例如来自collections
模块的类,或者进行封装而不是继承。 (UserString
类使用封装。)或者从头开始。You know the saying: "You know what happens when you assume." :-)
They don't officially document that stuff because they may decide to change it in the future. Any unofficial documentation you may find would simply document the current behavior of one Python implementation, and relying on it would result in your code being very, very fragile.
When there is official documentation of special methods, it tends to describe behavior of the interpreter with respect to your own classes, such as using
__len__()
when__nonzero__()
isn't implemented, or only needing__lt()__
for sorting.Since Python uses duck typing, you usually don't actually need to inherit from a built-in class to make your own class act like one. So you might reconsider whether subclassing
dict
is really what you want to do. You might choose a different class, such as something from thecollections
module, or to encapsulate rather than inheriting. (TheUserString
class uses encapsulation.) Or just start from scratch.您可以创建自己的类,该类具有您想要的属性,而不是子类化
dict
,而无需太多麻烦。这是一篇 博客 文章,其中包含如何执行此操作的示例。其中的 __str__() 方法并不是最好的,但是很容易纠正,其余的方法可以提供您想要的功能。Instead of subclassing
dict
, you could instead just create make your own class that has exactly the properties you want without too much trouble. Here's a blog post with an example of how to do this. The__str__()
method in it isn't the greatest, but that's easily corrected the rest provide the functionality you seek.