Python 语言中, 不同类型对象之间的比较规则浅析
今天为了捉一个臭虫耗废了近一个小时,最后发现是 if foo > 1:
这里的foo实际是字符串,导致foo
是"0"
时,"0" > 1
为真。于是便花了点时间研究了下Python
比较运算规则。
在Python2
中,比较运算遵循以下规则:
- 数字和数字按大小排序 (数字类型包括 int, float, long, complex, bool)
- 字符串按字符串按字典序排序(str, unicode)
- 数字类型和非数字类型比较,除None外,数字类型总是小于非数字类型。
- 两个非数字不同类型,按其类型名的字典与排序
- 第4点有一个特例,老式类的实例总是小于新式类
- 非数字/字符串类型的同一类型的不同实例的比较,如果类定义了
__cmp__()
方法,则用该方法比较 - 同上,若类型没定义
__cmp__()
方法, 则按实例在内存中的地址排序 - None < None
- 3,4,5,7 是CPython的实现,不是Python语言自身的标准,参见[CPython implementation detail][]。 Python语言只要求对非数字和字符串类型的不同对象的比较,总是不想等的,比较结果可以是任意的,但必须是一致的(即多次比较,结果恒定)。
Python3
终于修了这个bug ( What’s New In Python 3.0 ), 规则如下:
- incomparable类型对象比较 \<, \<=, >=, > 会 raise
TypeError
- incomparable类型对象比较 !=, == 仍是合法的,但总为
False
cmp()
和__cmp__()
方法被弃置了,取而代之的是__lt__()
,__eq__()
,__hash__()
...
Python2
当初会设计这种比较规则,可能是为了便于对包含不同类型对象的容器排序。list.sort()
和sorted()
都仿照了C/C++里的sort
。Python2.4
后sort
使用key
来比较不同对象显然更Pythonic
更多例子,参见Sorting Mini-HOW TO