对对象施加任意顺序。排序仅被定义为在程序执行中是稳定的。
这意味着在比较任意对象时由 Python 实现定义排序。如果类型相同,CPython 使用内存地址(来自C 源):
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()