6

我遇到了魔术比较方法的一些令人困惑的行为。假设我们有以下类:

class MutNum(object):
    def __init__ (self, val):
        self.val = val

    def setVal(self, newval):
        self.val = newval

    def __str__(self):
        return str(self.val)

    def __repr__(self):
        return str(self.val)

    # methods for comparison with a regular int or float:
    def __eq__(self, other):
        return self.val == other

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

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

    def __ge__(self, other):
        return self.__gt__(other) or self.__eq__(other)

    def __le__(self, other):
        return self.__lt__(other) or self.__eq__(other)

该类做了它应该做的事情,将 MutNum 对象与常规 int 或 float 进行比较是没有问题的。然而,这是我不明白的,当魔术方法被赋予两个 MutNum 对象时,它甚至比较好。

a = MutNum(42)
b = MutNum(3)
print(a > b) # True
print(a >= b) # True
print(a < b) # False
print(a <= b) # False
print(a == b) # False

为什么这行得通?谢谢。

4

2 回答 2

5

它评估如下(使用类似repr符号而不是引用变量):

   MutNum(42) > MutNum(3)
=> MutNum(42).__gt__(MutNum(3))
=> MutNum(42).val > MutNum(3)
=> 42 > MutNum(3)

从那里开始,这只是您已经知道有效的 int-MutNum 比较。

于 2013-11-01T16:56:47.383 回答
2

如果你加入一些 print 和/或 sys.stderr.write,我想你会看到发生了什么。例如:

def __gt__(self, other):
    sys.stderr.write('__gt__\n')
    sys.stderr.write('{}\n'.format(type(other)))
    sys.stderr.write('{} {}\n'.format(self.val, other))
    result = self.val > other
    sys.stderr.write('result {}\n'.format(result))
    return result

def __lt__(self, other):
    sys.stderr.write('__lt__\n')
    sys.stderr.write('{}\n'.format(type(other)))
    sys.stderr.write('{} {}\n'.format(self.val, other))
    result = self.val < other
    sys.stderr.write('result {}\n'.format(result))
    return result

当您尝试将 self.val (an int) 与 other (a MutNum) 进行比较时,python 意识到它无法将 int 与 MutNum 进行比较,并颠倒比较的顺序,并将 MutNum 与 int 进行比较 - 这是你定义的东西。也就是说,单个 > 比较正在执行您所期望的 >,但它也在执行 <。

于 2013-11-01T17:26:50.547 回答