我遇到了魔术比较方法的一些令人困惑的行为。假设我们有以下类:
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
为什么会这样?谢谢。
它的计算结果如下(使用类似repr
的表示法而不是引用变量):
MutNum(42) > MutNum(3)
=> MutNum(42).__gt__(MutNum(3))
=> MutNum(42).val > MutNum(3)
=> 42 > MutNum(3)
从那里开始,这只是您已经知道有效的int-MutNum比较。
如果你加入一些打印和/或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(一个int)与其他(一个MutNum)进行比较时,python意识到它没有将int与MutNum进行比较,并颠倒了比较的顺序,并将MutNum与int进行比较 - 这是你定义的东西。 也就是说,单个>比较正在按照您的预期进行>,但它也正在执行<。