2011-11-26 32 views
22

私は、Python 2のコードを使用する場合、それは私にエラーのpython 2とPython 3 __cmp__

class point: 

     def __init__(self,x,y): 
      self.x=x 
      self.y=y 

     def dispc(self): 
      return ('(' +str(self.x)+','+str(self.y)+')') 

     def __cmp__(self,other): 
      return ((self.x > other.x) and (self.y > other.y)) 

を与えるPythonの3ながら、それが正常に動作します............... .................................................. ...

[email protected]:~/Documents/Programs$ python3 -i classes.py 
>>> p=point(2,3) 
>>> q=point(3,4) 
>>> p>q 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unorderable types: point() > point() 
>>> 
[email protected]:~/Documents/Programs$ python -i classes.py 
>>> p=point(2,3) 
>>> q=point(3,4) 
>>> p>q 
False 
>>> 

........................................ ...........................

==とのみで動作している間は、python 3ではandにエラーがあります。

解決策をご提案ください。

答えて

29

Python 3で注文するには__lt____eq__メソッドを提供する必要があります。__cmp__は使用されなくなりました。

__lt__以下の質問/コメントへの応答に更新

は、引数としてselfotherを取り、self未満otherであるかどうかを返す必要があります。たとえば、次のように

class Point(object): 
    ... 
    def __lt__(self, other): 
     return ((self.x < other.x) and (self.y < other.y)) 

あなたは次のような状況持っている場合:

p1 = Point(1, 2) 
p2 = Point(3, 4) 

p1 < p2 

これはと同等になります。

p1.__lt__(p2) 

Trueを返します。 __eq__は、ポイントが等しい場合はTrue、そうでない場合はFalseを返します。下記の推奨どおりにfunctools.total_orderingデコレータを使用する場合は、あなただけの__lt____eq__を提供する必要がありますのpython3で

from functools import total_ordering 

@total_ordering 
class Point(object): 
    def __lt__(self, other): 
     ... 

    def __eq__(self, other): 
     ... 
+4

PEP 8勧告は、すべての6つの豊富な比較を提供することです。簡単にするには、* functools.total_ordering *を使用してください。 –

+1

__cmp__の代わりに__ltと__eq__を使用するにはどうすればよいですか? –

+0

さて、「lt」はLess Thanの略です。 'self'が他のパラメータよりも小さいかどうかを示すブール値を返します。他は同様に動作します。私はあなたが詳細を理解することができると確信しています。 –

8

これはPython 3の主な変更です。詳細はhereを参照してください。

2

6つの豊富な比較演算子

__lt__(self, other) 
__le__(self, other) 
__eq__(self, other) 
__ne__(self, other) 
__gt__(self, other) 
__ge__(self, other) 

を個別に提供されなければなりません。これは、functools.total_orderingを使用して省略することができます。

これは、ほとんどの場合、読めなくて実用的ではありません。それでも、2つの機能に同じようなコードを入れる必要があります。あるいは、さらにヘルパー機能を使用する必要があります。

ほとんどの場合、以下に示すmixinクラスPY3__cmp__を使用することをお勧めします。これは、単一の__cmp__メソッドフレームワークを再構築します。ほとんどの場合、非常に明確で実用的でした。それでも、選択された豊富な比較を無効にすることができます。

あなたの例では、ちょうどになる:

class point(PY3__cmp__): 
     ... 
     # unchanged code 

PY3__cmp__ミックスインクラス:

PY3 = sys.version_info[0] >= 3 
if PY3: 
    def cmp(a, b): 
     return (a > b) - (a < b) 
    # mixin class for Python3 supporting __cmp__ 
    class PY3__cmp__: 
     def __eq__(self, other): 
      return self.__cmp__(other) == 0 
     def __ne__(self, other): 
      return self.__cmp__(other) != 0 
     def __gt__(self, other): 
      return self.__cmp__(other) > 0 
     def __lt__(self, other): 
      return self.__cmp__(other) < 0 
     def __ge__(self, other): 
      return self.__cmp__(other) >= 0 
     def __le__(self, other): 
      return self.__cmp__(other) <= 0 
else: 
    class PY3__cmp__: 
     pass 
+0

私はあなたが演算子を書いた方法が好きだった。しかし、このステートメント(a> b) - (a theBuzzyCoder

+1

@theBuzzyCoder 'bool'は' int'のサブクラスなので、 'True'と' False'は基本的にそれぞれ1と0です。 'cmp'は最初の引数が2番目の引数よりも小さい場合は負の値を返し、そうでない場合は0を返します。そうでない場合は' False-False == 0'、 'True-False = = 1'、 'False - True == -1'は' cmp'の正しい戻り値を提供します。 – chepner

関連する問題