2013-11-01 10 views
5

私は魔法の比較メソッドのいくつかの混乱した動作に遭遇しました。 たちは以下のクラスがあるとします。Pythonのマジックメソッドの混乱

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) 

クラスは、行うことになっているものを行い、通常のintまたはfloatにMutNumオブジェクトを比較することは問題ありません。しかし、これは私が理解していないことです。マジックメソッドに2つの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 

これはなぜ機能しますか?ありがとう。次のように

+1

たとえば、 '__gt__'と' __lt__'は '__add__'と' __radd__'と同じ関係にあると考えるのが役に立ちます。最初のものが適用されない場合、Pythonはオペランドを逆にしてもう一方を試みます。 – chepner

答えて

4

それは(repr様の表記を使用しての代わりに、変数を参照)評価:

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

そしてそこから、それはあなたがすでに作品を知っているだけでINT-MutNum比較ですです。

+0

@dust *このクラスのインスタンスに対する通常のintとfloatの比較は問題ではありません;-) '42> ...'は 'MutNum'ではなく' MutNum .__ gt__'をもう一度起動しません。このような混乱は、あなたが持っているように '__repr__'を定義しないで、' MutNum'をラップする番号から区別する何かを加える理由の1つです。 – 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 

あなたは(MutNum)他にself.val(int)を比較しようとすると、PythonはそれがMutNumにint型を比較す​​るために何も持っていません実現し、比較の順序を逆にして、あなたが定義したものであるintにMutNumを比較します。つまり、あなたが期待しているように> 1つの比較が>をしていますが、<も行っています。