自定义类排序:没有抛出错误,Python测试的目的是什么?

自定义类排序:没有抛出错误,Python测试的目的是什么?,python,object,python-2.x,comparison-operators,Python,Object,Python 2.x,Comparison Operators,在没有指定对象的相等比较属性的情况下,Python在使用和编辑时仍然在做一些事情:阅读后查看更新!完全正确的答案是“未定义,但一致” 它测试的是repr(me)vsrepr(you),本质上就是做字符串比较。下面是一个容易看到的示例: class A(object): pass class B(object): pass x = A() # <__main__.A object at 0x7f7014e4e2d0> y = B() # <__main__.B object

在没有指定对象的相等比较属性的情况下,Python在使用
编辑时仍然在做一些事情:阅读后查看更新!完全正确的答案是“未定义,但一致”

它测试的是
repr(me)
vs
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)
A类(对象):通过
B类(对象):通过
x=A()#
y=B()#
z=A()
x
我同意这对我来说有点奇怪。也许有一个我不知道的很好的理由

更新:我对
repr
的看法是错误的,尽管它看起来确实在测试中使用了基本
对象
repr


其中有一行说明“一个对象被视为比另一个对象小还是大的选择是任意的,但在程序的一次执行中是一致的。”换句话说,它可能使用
repr
,但这不能保证。但是,这将是一致的。如果没有丰富的比较运算符,Python将使用对象的
repr()
。(至少,这对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()
对对象施加任意顺序。排序仅定义为

这意味着在比较任意对象时,由Python实现定义顺序。如果类型相同,则CPython使用内存地址(从中):


在上面的例子中,它使用的是
repr
,而不是
id
。是的,它不是对象id,我已经测试过了。关于
repr
测试的任何参考资料?有相关文档吗?这显然是错误的。带有
\uuuu repr\uuuu()钩子的自定义类不能通过为
repr(实例)
返回不同的值来改变它们的顺序。因此,没有任何迹象表明
repr
参与了排序。好吧,这有点随机?这对我来说似乎很危险,也没有必要。为什么不像其他相等操作一样抛出一个错误呢?好的,那么这就是要比较的内存地址的字符串表示形式?i、 e.
0x162afd0
vs
0x162afd0
@ravidicus:正在比较的是实际内存地址。默认的
repr()
返回值包含内存地址的十六进制表示,但这不是用于比较的。例如,您可以提供一个自定义的
\uuu repr\uuu()
钩子,它不会改变顺序(或内存地址)。@如果类是同一类型,它将使用内存。Martijn的回答很好,比我的回答更彻底。明白了。谢谢,我将把这个标记为已接受。但我还是不喜欢也不理解其中的逻辑@爬行动物:逻辑是这是一个错误,现在它在py3k中被修复了。
class A(object): pass
class B(object): pass
l = [A() if i % 2 else B() for i in range(1000)]
l.sort()
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;
}
>>> class Foo(): pass
... 
>>> Foo() < Foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: Foo() < Foo()