オブジェクトには任意の順序が課されます。順序付けは、プログラム実行内で安定するように定義されているだけです。
これは、任意のオブジェクトを比較するときの順序を定義するのは 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()