自定义链式比较

acd*_*cdr 16 python

Python允许使用类似的表达式x > y > z,根据文档,这些表达式相当于(x > y) and (y > z)除了y只计算一次.(https://docs.python.org/3/reference/expressions.html)

但是,如果我自定义比较功能,这似乎会中断.例如,假设我有以下类:(对于大块的道歉,但是一旦你阅读了这个__eq__方法,其余的都是微不足道的.)

class CompareList(list):
    def __repr__(self):
        return "CompareList([" + ",".join(str(x) for x in self) + "])"

    def __eq__(self, other):
        if isinstance(other, list):
            return CompareList(self[idx] == other[idx] for idx in xrange(len(self)))
        else:
            return CompareList(x == other for x in self)

    def __ne__(self, other):
        if isinstance(other, list):
            return CompareList(self[idx] != other[idx] for idx in xrange(len(self)))
        else:
            return CompareList(x != other for x in self)

    def __gt__(self, other):
        if isinstance(other, list):
            return CompareList(self[idx] > other[idx] for idx in xrange(len(self)))
        else:
            return CompareList(x > other for x in self)

    def __ge__(self, other):
        if isinstance(other, list):
            return CompareList(self[idx] >= other[idx] for idx in xrange(len(self)))
        else:
            return CompareList(x >= other for x in self)

    def __lt__(self, other):
        if isinstance(other, list):
            return CompareList(self[idx] < other[idx] for idx in xrange(len(self)))
        else:
            return CompareList(x < other for x in self)

    def __le__(self, other):
        if isinstance(other, list):
            return CompareList(self[idx] <= other[idx] for idx in xrange(len(self)))
        else:
            return CompareList(x <= other for x in self)
Run Code Online (Sandbox Code Playgroud)

现在我可以做有趣的事情CompareList([10, 5]) > CompareList([5, 10]),它会正确返回CompareList([True,False])

但是,链接这些操作不能很好地工作:

low = CompareList([1])
high = CompareList([2])
print(low > high > low) # returns CompareList([True])
Run Code Online (Sandbox Code Playgroud)

为什么不?引擎盖下发生了什么?我知道它不等于(low > high) > low= (False > low)(因为那将返回False).它可能是low > (high > low)但在操作符优先级(通常是从左到右)方面没有意义.

AKS*_*AKS 8

Python允许使用类似的表达式x > y > z,根据文档,这些表达式相当于(x > y) and (y > z)除了y只计算一次.

据此,low > high > low将相当于(low > high) and (high > low).

>>> x = low > high   # CompareList([False])
>>> y = high > low   # CompareList([True]) 
>>> x and y
CompareList([True])
Run Code Online (Sandbox Code Playgroud)

更多来自x和y的文档:

x and y:如果x是假,那么x,否则y

在上述情况中:

>>> x is False
False
>>> x if x is False else y     # x and y
CompareList([True])
Run Code Online (Sandbox Code Playgroud)

所以当你这样做时x and y,返回的yCompareList([True]).