Python魔法方法混乱

Python魔法方法混乱,python,comparison,magic-methods,Python,Comparison,Magic Methods,我遇到了魔法比较法的一些令人困惑的行为。 假设我们有以下类: 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): r

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

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)
class MutNum(对象):
定义初始值(self,val):
self.val=val
def setVal(自我,新值):
self.val=newval
定义(自我):
返回str(self.val)
定义报告(自我):
返回str(self.val)
#与常规int或float进行比较的方法:
定义(自身、其他):
return self.val==其他
定义(自身、其他):
返回self.val>other
定义(自身、其他):
return self.val
该类执行它应该执行的操作,将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
a=MutNum(42)
b=MutNum(3)
打印(a>b)#正确
打印(a>=b)#正确
打印(arepr
的符号,而不是引用变量):


从这里开始,你知道的只是int-MutNum比较。如果你加入一些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
def\uuugt\uuuuuu(自身、其他):
系统标准写入(“”\u gt \u\n’)
sys.stderr.write('{}\n'.格式(类型(其他)))
sys.stderr.write('{}{}\n'.格式(self.val,other))
结果=self.val>其他
sys.stderr.write('result{}\n'.格式(result))
返回结果
定义(自身、其他):
系统标准写入(“”\u lt \u\n’)
sys.stderr.write('{}\n'.格式(类型(其他)))
sys.stderr.write('{}{}\n'.格式(self.val,other))
结果=self.val<其他
sys.stderr.write('result{}\n'.格式(result))
返回结果

当您尝试将self.val(int)与其他(MutNum)进行比较时,python意识到它没有用于比较int和MutNum的功能,并颠倒了比较的顺序,将MutNum和int进行比较,这是您定义的。也就是说,一个>比较就像您预期的那样执行>操作,但它也执行@dust操作。您说过,将常规int和float与此类实例进行比较不是一个简单的操作问题;-)
42>。
不会再次调用
MutNum.\uu gt\uuu
,因为42不是
MutNum
。这种混淆是一个原因,不应该像你所拥有的那样定义
\uuuu repr\uuuuu
,而应该添加一些区别
MutNum
和它所包装的数字的东西。例如,想想
\uu gt\uuuuu
\uu lt\uuuuuuuuuu
\uuu add\uuuu
处于相同的关系,可能会有所帮助。如果第一个不适用,Python将尝试另一个,并反转操作数。
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