2012-08-07 9 views
5

次のコードを完成させる最も自然な方法は何ですか?比較演算子を実装する際の混在型の扱い方は?

import functools 

@functools.total_ordering 
class X: 
    def __init__(self, a): 
     self._a = a 

    def __eq__(self, other): 
     if not isinstance(other, X): 
      return False 
     return self._a == other._a 

    def __lt__(self, other): 
     if not isinstance(other, X): 
      return ...     // what should go here? 
     return self._a < other._a 

if __name__ == '__main__': 
    s = [2, 'foo', X(2)] 
    s.sort() 
    print s 

答えて

2

あなたは自然に感じるものを選択できます。 Falseは、あなたのインスタンスが他のタイプの後で常にソートすることを意味します。Trueとそれらは前にソートされます。その場合には豊富な比較方法は、シングルトンNotImplementedを返すことが

def __lt__(self, other): 
    if not isinstance(other, X): 
     return NotImplemented 
    return self._a < other._a 

は、文書を引用:

代わりに、比較がサポートされていない合図する(the __lt__ and other comparison methods documentationを参照)NotImplementedを返すことができます。与えられた引数の組に対する演算を実装していません。慣例により、成功した比較のためにFalseTrueが返されます。ただし、これらのメソッドは任意の値を返すことができるので、比較演算子がブールコンテキスト(if文の条件など)で使用されている場合、Pythonはbool()を呼び出して結果が真か偽かを判定します。

+1

ちょうどFalseまたはTrueを返すことはお勧めできません。別の類似クラスYがあり、X( 'foo') X( 'foo')の場合を考えてみましょう。結果は一貫していない可能性があります。 – user763305

+1

しかし、NotImplementedを返すと機能します。そして、Pythonは独自のデフォルト順序を使用しますが、これはやや恣意的ですが一貫しています。 – user763305

4

私の個人的なアプローチ:

例外。

さまざまな種類の間に自然順序はありません。

公式1:(があるはず、このいずれかを選択)

私は完全にそれに同意しないが、マニュアルは明確にそれが行われるべきかを述べて:

http://docs.python.org/library/stdtypes.html#comparisons

異なる数値型と 異なる文字列型を除いて、異なる型のオブジェクトは、等価を比較しません。そのようなオブジェクトは一貫しているが任意に( の異種配列を並べ替えると一貫した結果が得られるように)並べ替えられます。さらに、一部のタイプ(たとえば、 ファイルオブジェクト)は、 の2つのタイプのオブジェクトが等しくない場合の比較の縮退した概念のみをサポートしています。ここでも、このようなオブジェクトは任意に一貫して と命名されています。 <,< =、>および> =演算子は、オペランドが複素数の場合は にTypeError例外を送出します。

これは基本的に...私は例外を発生させますが、注文を行う最も無邪気な方法はマニュアルに従うことです。

これを実行するには、1つ、好ましくは1つの方法が必要です。

+0

しかし、Pythonはこのような命令を実装しています。リストを並べ替えることができます[2.3、 'foo'、int]。 – user763305

+0

'1> '文字列'は偽です、' 1 <'文字列'は真です。 –

+0

具体的には、 'TypeError("は{}と{} "を比較できません。(format(self)、type(other)))' – ecatmur

関連する問題