带有“__getitem__”的类没有“get”方法

Posted

技术标签:

【中文标题】带有“__getitem__”的类没有“get”方法【英文标题】:Class with '__getitem__' has no 'get' method 【发布时间】:2019-09-15 09:58:13 【问题描述】:

我意识到没有get 方法的类自然就没有get 方法。将get 方法添加到实现__getitem__ [没有样板] 的类中的最佳方法是什么?

我试过了:

class Foo():
    def __getitem__(self, item):
        ...

    get = dict.get  # TypeError

但是python抱怨:

TypeError: descriptor 'get' for 'dict' objects doesn't apply to 'Foo' object

显然collections.UserDict 可以使用,但我希望是懒惰的(因为分辨率很昂贵)并且不填充项目数据,直到它被访问(并通过Foo 对象上的键缓存)。

想法?

【问题讨论】:

方法? 您提到希望您的代码懒惰并避免昂贵的工作,但目前还不清楚您如何才能懒惰地为类字典类实现get。您希望跳过的具体工作是什么? 您似乎还想使用 collections.abc.Mapping 抽象基类的 mixin 方法。如果你使用它作为你自己类型的基类,你只需要实现__getitem____len____iter__,它就会给你剩下的所有(只读)映射API。如果你想可变,那就从MutableMapping继承,并添加__setitem____delitem__ 由于您的类不是 dict(或其中的子类),您需要 def get(self, <args...>): 并定义它的含义/作用。 【参考方案1】:

并不是说get方法过于复杂,我希望python有内置函数来减少这种样板......

class Foo():
    ...
    def get(self, item, default):
        try:
            return self[item]
        except KeyError as err:
            return default

【讨论】:

@Sanyash:看起来像是对我的回答。问题:你如何给这个类这个方法?答:写方法。 @Sanyash 我同意,但模组倾向于同意冻结有用的帖子,所以我希望在发布时有一个答案,以便未来的谷歌人能够摆脱 soemthing这篇文章。 顺便说一下,IndexError 是序列的例外。 KeyError 用于映射。 get 方法更常见于映射而不是序列,所以你的 __getitem__ 似乎提高了 IndexError 有点奇怪。 如果您将此答案的内容移至您的问题,未来的 Google 员工仍会从您的帖子中获取此内容。 1.如果您还对IndexErrorKeyError 的兄弟姐妹)感兴趣,那么“父”例外是LookupError。 2.考虑将default默认为None

以上是关于带有“__getitem__”的类没有“get”方法的主要内容,如果未能解决你的问题,请参考以下文章

为啥当我使用 [:] 时我的子类的 __getitem__ 和 __setitem__ 没有被调用?

为啥 __getitem__(key) 和 get(key) 比 [key] 慢很多?

getitem

如何让 Python 2 的 __getitem__ 在类上工作? [复制]

面向对象进阶——内置方法

TypeError 'x' 对象没有属性 '__getitem__'