2017-03-11 4 views
4

私は、基底と高さを__init__引数とするクラスTriangleをPythonで宣言しました。そして、areaは三角形の面積を計算して返します。 Triangleクラスの__eq__メソッドは、三角形の面積を比較し、値を返します。クラスは以下のように定義されます。__eq__メソッドは、==と>の両方の演算子に対してTrueを返します

class Shape(object): 
    def area(self): 
     raise AttributeException("Subclasses should override this method.") 

class Triangle(Shape): 
    def __init__(self, base, height): 
     """ 
     base = base of the triangle. 
     height = height of the triangle 
     """ 
     self.base = base 
     self.height = height 
    def area(self): 
     return (self.base * self.height)/2 
    def __str__(self): 
     return 'Triangle with base ' + str(self.base) + ' and height ' + str(self.height) 
    def __eq__(self, other): 
     """ 
     Two triangles are equal if their area is equal 
     """ 
     return (self.area() == other.area()) 

今、私はプログラムを実行し、Trianglet1t3に2つのインスタンスを作成し、それらに異なる塩基と高さを与えたが、その面積は同じです。したがって、t1 == t3Trueであり、Trueとして返されます。しかし、不思議なことに、も返されますが、それはなぜわかりませんか?True

>>> t1 = Triangle(3,4) 
>>> t3 = Triangle(2, 6) 
>>> t1.area() 
6 
>>> t3.area() 
6 
>>> t1 == t3 
True 
>>> t1 > t3 
True 
>>> t1 < t3 
False 
>>> 
+1

。 – L3viathan

+2

どのように '__gt__'を実装しましたか? –

+1

クラス全体を追加しました。その簡単な学習例は、私は__eq__を定義しました。 –

答えて

3

私はこの上のソースを見つけることができませんが、Pythonの2を使用して、それぞれの魔法のメソッドを自分で定義していない場合は2つのオブジェクトを比較するためにidを使用しているかのように、それはそうです。

守っ:

>>> t1 = Triangle(3, 4) 
>>> t3 = Triangle(2, 6) 
>>> t1 > t3 
False 
>>> t1 < t3 
True 
>>> t1 = Triangle(3, 4) 
>>> t1 > t3 
True 
>>> t1 < t3 
False 

idは与える以来、idは後で作成されたオブジェクトに番号を増やす割り当てることを約束しませんが、通常CPythonの2.7で動作するようには思えないので、この動作は保証されませんあなたはオブジェクトの物理アドレスです。

t1の再定義の前には、id(t1) < id(t3)が続きますが、それ以降は逆の場合があります。

+0

あなたはCPythonでは、新しいオブジェクトの数が増えていることが保証されているので、Cpythonでは一貫性がありますが、Pythonでは保証されません。 –

+2

@GauravSachdevaそのようなことは保証されていません。CPythonでは、 'id'はオブジェクトの物理アドレスです。利用可能なスペースがあればどこでもかまいません(通常、最初に番号が増えていきます...) – zvone

2

this answerに記載docs

If no __cmp__(), __eq__() or __ne__() operation is defined, class instances are compared by object identity (“address”).

によれば、パイソン2デフォルトの新しいバージョンは、比較のために、オブジェクトのIDを使用します。

__gt__または__lt__のいずれかを、__eq__と一緒に定義して、必要な方法を比較する必要があります。あなたが望むなら、あなたはまた、あなたが変更することができ__le____ge____ne__ ...

一つの簡単なものを定義することができます:あなたが問題を再現するために、あなたのクラスを十分に示していない

class Triangle(Shape): 
    def __init__(self, base, height): 
     """ 
     base = base of the triangle. 
     height = height of the triangle 
     """ 
     self.base = base 
     self.height = height 
    def area(self): 
     return (self.base * self.height)/2 
    def __str__(self): 
     return 'Triangle with base ' + str(self.base) + ' and height ' + str(self.height) 
    def __eq__(self, other): 
     """ 
     Two triangles are equal if their area is equal 
     """ 
     return (self.area() == other.area()) 
    def __gt__(self, other): 
     """ 
     This works for both greater than and less than 
     """ 
     return (self.area() > other.area()) 
+0

おそらく '__gt__'、' __lt__'、 '__ge__'、' __le__'、 __eq__'、 '__ne__'を同時に使用するか、[total_ordering](https://docs.python.org/2/library/functools.html#functools.total_ordering)を使用してください。さらに重要なのは、 '__eq__'を実装するときに常に' __hash__'を実装すべきです。そうでないと(例えば 'dict')予期せずに壊れることがあります。 – zvone

関連する問題