Python:默认比较
在Python 2.7中,我定义了一个空的新式类:
In [43]: class C(object): pass
....:
然后我创建了这个新类的实例列表:
In [44]: c = [C() for i in xrange(10)]
接着我尝试对这个列表进行排序:
In [45]: sorted(c)
Out[45]:
[<__main__.C object at 0x1950a490>,
<__main__.C object at 0x1950a4d0>,
...
<__main__.C object at 0x1950aad0>]
令人惊讶的是,排序并没有报错,尽管我并没有定义如何比较这个类的实例C
:
In [46]: dir(C())
Out[46]:
['__class__',
'__delattr__',
'__dict__',
'__doc__',
'__format__',
'__getattribute__',
'__hash__',
'__init__',
'__module__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__']
那么,这到底发生了什么呢?这种行为的原因是什么呢?
3 个回答
0
看看你打印出来的值。注意“Object C at”旁边的那个十六进制数字吗?那是一个指针引用。简单来说,它可以大致理解为创建的顺序。如果你遍历那个列表,你会发现它是根据这个顺序来排序对象的。
顺便提一下,我记得我曾经对Python 2.x的比较感到困惑……不过我不确定这个问题在Python 3中是否解决了。
1
我不是很确定,但也许有人可以纠正我。
当你比较对象时,其实是在比较它们在内存中的地址,就像在C语言中比较两个字符串一样。如果你仔细看看,排序是把对象从内存地址最低的排到最高的(或者说是指针的位置)。
16
我觉得这样做的唯一理由是,方便对象可以被排序,并且可以用作字典的键,具有一些默认的行为。相关的内容可以在这个语言定义的章节找到:https://docs.python.org/2/reference/expressions.html#not-in
“判断一个对象是否比另一个对象小或大,这个选择是随意的,但在程序执行的过程中是保持一致的。”
所以,目前对象是通过内存地址来比较的这个事实,只是一个实现细节,并不能完全依赖。唯一可以保证的是,在执行过程中,排序的顺序是保持一致的。