2016-06-17 6 views
0

以下のコードでは、魔方法__lt__()で '<'を定義しました。最初の引数が2番目の引数よりも小さい場合はTrueを返し、そうでない場合はFalseを返します。Python3:なぜ比較は自然に行われますか?

from functools import total_ordering 

@total_ordering 
class Currency: 
    """ 
    One object of class Currency stores one amount of money, dollars and cents. 
    """ 

    def __add__(self, other): 
     """ 
     returns the result of adding self to other 
     """ 
     total = Currency(self.dollars, self.cents) 
     total.dollars = total.dollars + other.dollars 
     print (other.dollars) 
     total.cents = total.cents + other.cents 
     print (other.cents) 
     if total.cents > 100: 
      total.cents = total.cents - 100 
      total.dollars = total.dollars +1 
     return total 

    def __init__(self, dollars=0, cents=0): 
     self.dollars = dollars 
     self.cents = cents 

    def __str__(self): 
     return "$"+str(self.dollars)+"."+str(self.cents) 

    def __eq__(self, other): 
     return self.dollars==other.dollars and self.cents==other.cents  

    def __lt__(self, other): 
     if self.dollars<other.dollars: 
      return True 
     elif self.dollars > other.dollars: 
      return False 
     else: # dollars are equal 
      return self.cents < other.cents 

は、そして私は '<' でテストプログラムで__lt__()と呼ばれます。この場合、candyPrice(最初の引数)はbookPrice(2番目の引数)より小さいため、期待通りにTrueを返します。そして、私はこれらの2つの値をclass Currencyであらかじめ定義されていない '>'と比較しましたが、期待通りにFalseを返しました。 __lt__()が既に定義されているのであれば、逆の表現である '>'式も暗黙的に定義されているのでしょうか?

if __name__ == "__main__": 
    candyPrice = Currency (1, 17) # $1.17 
    bookPrice = Currency (12, 99) # $12.99 

    print (candyPrice < bookPrice) 
    print (candyPrice > bookPrice) 
+0

同じ価格の引数を使用してプログラムをテストしましたか? – Kairat

+0

@Kairatはい、しました。そして私はそれを私の質問に加えます。ありがとうございます –

+0

比較に 'print'文を入れてみてください。それは呼び出されているものを表示します。一般的に、* no *、 '__gt__'は定義されていません。'__rle__'のようなものを定義すると' candy> book'は 'book dwanderson

答えて

3

@total_orderingクラスデコレータを使用しました。このデコレータは他のメソッドを明示的に追加します@functools.total_ordering documentationから

は、メソッドを注文する1つの以上の豊富な比較を定義するクラスを考えると、このクラスのデコレータは残りを供給します。これは、可能な豊富な比較演算の全てを指定するのに労力を簡素化:

クラスは__lt__()の1、__le__()__gt__()、または__ge__()を定義する必要があります。さらに、クラスは__eq__()メソッドを提供する必要があります。

あなたが__gt__メソッドを定義していないにもかかわらずので、クラスのデコレータは一緒__eq__で、あなたの__lt__メソッドを使用してのための1つを定義しています。例えば

は、__lt__方法を定義するときに、__gt__()実装に設定されている:self < otherが偽であれば

def _gt_from_lt(self, other, NotImplemented=NotImplemented): 
    'Return a > b. Computed by @total_ordering from (not a < b) and (a != b).' 
    op_result = self.__lt__(other) 
    if op_result is NotImplemented: 
     return op_result 
    return not op_result and self != other 

self != otherが使用されます。 __ne__メソッドを定義していませんが、__eq__を指定し、__ne__のデフォルト値はnot self.__eq__(other)です。デフォルトでは、

__eq__()から__ne__()代表者と、それはNotImplementedでない限り、結果を反転:object.__ne__() documentationを参照してください。テストCurrencyインスタンス__eq__については

が必要とされていない、trueを返しますので、FalsecandyPrice.__gt__(bookPrice)通話candyPrice.__lt__(bookPrice)は、self != otherをチェックせずに返されます。

関連する問題