【问题标题】:Assigning to double underscore methods (__eq__, __lt__, __gt__)分配给双下划线方法(__eq__、__lt__、__gt__)
【发布时间】:2015-09-10 13:05:37
【问题描述】:

在此示例中,我尝试分配新的__eq____lt____gt__ 方法,并通过将对象与文字3 进行比较来调用它们。为什么从未调用过bar(...)

class Foo:
    def __init__(self):
        self.__eq__ = self.bar
        self.__lt__ = self.bar
        self.__gt__ = self.bar

    def bar(self, other):
        print("bar called.")

a = Foo()
a == 3
a < 3
a > 3

this answer 中我找到了提示you can't assign new __eq__ to the object。不过,我找不到该声明的任何官方来源。

感谢任何提示和帮助!

编辑:我知道在对象本身中有定义__eq__ 的选项,但这个问题专门关于在实例创建后分配它。

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    Special Method Lookup:

    特殊方法的隐式调用只有在对象的类型上定义时才能保证正常工作,而不是在对象的实例字典中。

    如果目标是使用bar 进行比较,请在类级别分配它,而不是按实例分配(这也将通过不膨胀每个实例的属性字典来节省内存):

    class Foo:
        def bar(...):
            ...
        __eq__ = __lt__ = __gt__ = bar
    

    【讨论】:

    • 我不知道为什么我被否决了,我不认为这是一个微不足道的问题。不过谢谢你的回答!
    • 我怀疑是因为这类问题被问了很多(我基本上是从我对__call__ 的类似问题所做的评论中复制了我的答案)。我没有投反对票,但人们经常对他们认为多余的问题投反对票。
    • 显然我尝试过搜索,但我没有在 SO 上找到任何相关信息。但确实,我没想过尝试分配__call__,也许我可以找到更多信息。
    • 如果您需要能够覆盖每个实例,然后定义一些其他方法(例如_realeq)并定义__eq__(在类级别)来调用它。然后,您可以为实例分配自己的 _realeq,这不是特殊方法,将按您的预期调用。
    • 当我偶然发现这个问题时,我正在研究this question。我尝试在一个实例上替换dir(...) 列出的所有方法,但显然下划线方法失败了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 2021-11-28
    相关资源
    最近更新 更多