8

>オブジェクトの等値比較プロパティを指定しなくても、 Python はおよびを使用するときに何かを行っています<__gt__orを指定しない場合、実際にこれらのオブジェクトを比較するPythonは何__lt__ですか? を定義せずに 2 つのオブジェクトを一緒に追加しようとすると、サポートされていないオペランド エラーが発生することが予想されます__add__


In [1]: class MyObject(object):
   ...:     pass
   ...: 
In [2]: class YourObject(object):
   ...:     pass
   ...: 
In [3]: me = MyObject()
In [4]: you = YourObject()
In [5]: me > you
Out[5]: False
In [6]: you > me
Out[6]: True

4

3 に答える 3

6

オブジェクトには任意の順序が課されます。順序付けは、プログラム実行内で安定するように定義されているだけです。

これは、任意のオブジェクトを比較するときの順序を定義するのは Python 実装次第であることを意味します。タイプが同じ場合、CPython はメモリ アドレスを使用します ( C sourceから):

if (v->ob_type == w->ob_type) {
    /* When comparing these pointers, they must be cast to
     * integer types (i.e. Py_uintptr_t, our spelling of C9X's
     * uintptr_t).  ANSI specifies that pointer compares other
     * than == and != to non-related structures are undefined.
     */
    Py_uintptr_t vv = (Py_uintptr_t)v;
    Py_uintptr_t ww = (Py_uintptr_t)w;
    return (vv < ww) ? -1 : (vv > ww) ? 1 : 0;
}

同じ値が関数の基礎であり、カスタム クラスid()のデフォルト文字列でも表されるため、クラスの順序が決定されるように見える場合があります。行うのはメモリアドレスだけです。repr()repr()

同じ型ではないオブジェクトの場合、代わりに型名が使用され (数字のような型が他の型より前に並べ替えられます)、型が異なるが名前が同じである場合、コードは型のメモリ アドレスにフォールバックします (型が同じ場合のインスタンスのメモリ アドレスとは異なります)。

この暗黙の順序付けは、言語ではエラーと見なされ、Python 3 で修正されました

順序比較演算子 ( <<=>=>)TypeErrorは、オペランドに意味のある自然な順序がない場合に例外を発生させます。

これは、必要な順序付けフックを実装していないカスタム クラスに適用されます。

>>> class Foo(): pass
... 
>>> Foo() < Foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: Foo() < Foo()
于 2012-11-19T15:51:13.047 に答える
4

編集:読んだ後に更新を参照してください!完全に正しい答えは「未定義ですが、一貫しています」です。

これはテストであり、repr(me)本質repr(you)的に文字列の比較を行っています。見やすい例を次に示します。

class A(object): pass

class B(object): pass

x = A() # <__main__.A object at 0x7f7014e4e2d0>
y = B() # <__main__.B object at 0x7f7014e4e310>
z = A() # <__main__.A object at 0x7f7014e4e390>

x < z < y # True (assuming that the memory addresses are ordered as above)

これは私には少し奇妙に思えることに同意します。おそらく、私が気付いていないこれには正当な理由がありますか?

更新:テストでベースreprをrepr使用しているように見えますが、私は間違っています。http://docs.python.org/2/reference/expressions.html#not-inobject

「あるオブジェクトが別のオブジェクトよりも小さいか大きいかを選択するのは、プログラムの1回の実行内で任意に、しかし一貫して行われる」という行があります。言い換えれば、それは使用しているかもしれませんreprが、それは保証されていません。ただし、これは一貫して実行されます。

于 2012-11-19T15:31:00.307 に答える
0

repr()豊富な比較演算子がない場合、Pythonはオブジェクトを使用します。(少なくとも、これはPy2には有効です。Py3にはわかりません)。

だからあなたがするなら

class A(object): pass
class B(object): pass
l = [A() if i % 2 else B() for i in range(1000)]
l.sort()

オブジェクトは、最初repr()に来るもの、次に来るものの順に並べ替えられます。A()B()

于 2012-11-19T15:31:25.020 に答える