Python std 方法层次结构调用有记录吗?

发布于 2024-09-29 23:48:15 字数 264 浏览 8 评论 0 原文

刚刚在字典“类型”子类化中遇到了问题。我确实重写了 __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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

瞎闹 2024-10-06 23:48:15

来自 Mapping 或 MuteableMapping ="nofollow">集合模块而不是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)

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

Subclass Mapping or MuteableMapping from the collections module instead of dict 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:

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)

To subclass any of the builtin containers you should always use the appropriate baseclass from the collections module.

许久 2024-10-06 23:48:15

如果文档中未指定,则它是特定于实现的。 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 implement iterkeys 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.

何处潇湘 2024-10-06 23:48:15

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

他们没有正式记录这些内容,因为他们可能决定在将来更改它。您可能找到的任何非官方文档都只是记录了一个 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 the collections module, or to encapsulate rather than inheriting. (The UserString class uses encapsulation.) Or just start from scratch.

始终不够爱げ你 2024-10-06 23:48:15

您可以创建自己的类,该类具有您想要的属性,而不是子类化 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文