2013-11-01 4 views
5

나는 마법 비교 메소드의 혼란스러운 행동을 경험했다. 클래스는 일반 INT 또는 플로트에 MutNum 개체를 비교, 어떻게해야 무엇합니까파이썬 매직 메소드 혼동

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 개체가 주어지면 잘 비교됩니다.

왜이 기능이 작동합니까? 감사. (A repr -like 표기법을 사용하는 대신 변수 참조) 다음과 같이

+1

예를 들어,'__add__'와'__radd__ '와 같은 관계에있는'__gt__'과'__lt__'를 생각하면 도움이 될 것입니다. 첫 번째가 적용되지 않으면, 파이썬은 다른 피연산자를 반대로 시도합니다. – chepner

답변

4

그것은 평가 :

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

그리고 거기에서

, 그것은 당신이 이미 작동하는 단지 INT-MutNum의을 비교 한입니다.

+0

@dust * 당신은 *이 클래스의 인스턴스에 대한 정규 int와 float의 비교는 문제가되지 않는다고 말하며; 42)'42> ...'는'MutNum'이 아니기 때문에'MutNum .__ gt__'을 다시 호출하지 않을 것입니다. 이런 종류의 혼동은'__repr__'을 정의하지 않는 한가지 이유입니다. 그러나'MutNum'을 래핑하는 수에서 구별 할 수있는 것을 추가하십시오. – delnan

2

인쇄물 및/또는 sys.stderr.write를 던집니다. 무슨 일이 일어나고 있는지 알 것 같습니다. EG :

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 

당신의 (a MutNum) 다른 self.val (int를) 비교하려고 할 때, 파이썬이가 MutNum에 int를 비교 무관 실현하고 비교 순서를 반전시키고 MutNum을 int와 비교합니다. int는 사용자가 정의한 것입니다. 즉, 단일> 비교가 예상대로> 수행하고 있지만 <도 수행하고 있습니다.