【问题标题】:Chain overloaded comparison operators链式重载比较运算符
【发布时间】:2015-03-11 22:44:43
【问题描述】:

我想做这样的事情:

MyClass > 200 < 400  

该类实现了__gt__()__lt__() 方法,它们都返回self

class MyClass:

    ...

    def __gt__(self, value):
        DoCompareStuff(self, value)
        return self

    def __lt__(self, value):
        DoCompareStuff(self, value)
        return self

   ...

它将执行第一次评估,MyClass &gt; 200,但从不执行第二次评估,MyClass &lt; 400。似乎 Python 正在对返回值做一些事情,比如将其设为 TrueFalse。有没有办法做我想做的事情?

【问题讨论】:

  • 他们究竟为什么返回self?函数应根据比较结果返回真或假。这样,结果始终为真,除非您将类的布尔值定义为其他值。

标签: python python-2.7 python-3.x


【解决方案1】:

用于比较的运算符链接(请参阅the docs)意味着

MyClass > 200 < 400 

实际上被评估为:

(MyClass > 200) and (200 < 400)

因此,MyClass400 之间从未进行过比较。相反,你想要:

200 < MyClass < 400

评估为:

(200 < MyClass) and (MyClass < 400)

举个更简单的例子:

>>> class Demo(object):

    def __init__(self, value):
        self.value = value

    def __lt__(self, other):
        return self.value < other

    def __gt__(self, other):
        return self.value > other


>>> demo = Demo(250)
>>> 200 < demo < 400
True

注意这里的__lt____gt__ 实现有一个布尔返回(TrueFalse),而不是返回self(这将导致意外行为) .

【讨论】:

    【解决方案2】:

    首先,这段代码没有意义:

    MyClass > 200 < 400 
    

    当它扩展为:

    MyClass > 200 and 200 < 400 
    

    解析为:

    MyClass > 200
    

    其次,当涉及到布尔值时,Python 有一个强大的 "truthiness" 概念。这实质上意味着,任何不是零的东西都是“真实的”。

    最后,当你有这个代码时:

    def __gt__(self, value):
        DoCompareStuff(self, value)
        return self
    

    因为self 将是某种类型的对象,所以它总是,总是* 为真。例如,这两个都将评估为 true,因为您正在返回 self

    10 < MyClassInstance
    10 > MyClassInstance
    

    * 有时,except when you implement the __bool__ method。 (感谢@wim)

    【讨论】:

    • 总是总是sometimes.. 除外
    • @wim 天哪!太棒了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-07
    • 2011-03-07
    • 2018-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多