为什么Python允许可调用对象与数字比较?
我上周用Python写了一个作业,这里有一段代码:
def departTime():
'''
Calculate the time to depart a packet.
'''
if(random.random < 0.8):
t = random.expovariate(1.0 / 2.5)
else:
t = random.expovariate(1.0 / 10.5)
return t
你能看到问题吗?我把random.random和0.8进行了比较,其实应该是random.random()。
当然,这都是因为我粗心大意,但我不太明白。依我看,这种比较在任何编程语言中都应该至少给个警告。
那么为什么Python就这么忽略了,直接返回了False呢?
4 个回答
因为在Python中,这样的比较是完全有效的。Python无法判断你是否真的想进行这样的比较,或者你只是犯了个错误。你需要给Python提供正确的对象来进行比较。
由于Python的动态特性,你几乎可以用任何东西去比较和排序几乎所有的东西(这其实是个优点)。在这个例子中,你把一个函数和一个浮点数进行了比较。
举个例子:
list = ["b","a",0,1, random.random, random.random()]
print sorted(list)
这将会输出以下内容:
[0, 0.89329568818188976, 1, <built-in method random of Random object at 0x8c6d66c>, 'a', 'b']
在Python 3中,这个问题已经“修复”了。你可以查看这个链接了解更多信息:http://docs.python.org/3.1/whatsnew/3.0.html#ordering-comparisons。
这不一定是个错误
首先,得说明一下,这不总是一个错误。
在这个特定的例子中,比较显然是错的。
不过,由于Python的动态特性,看看下面这段(虽然很糟糕但完全有效的)代码:
import random
random.random = 9 # Very weird but legal assignment.
random.random < 10 # True
random.random > 10 # False
比较对象时到底发生了什么?
关于你提到的情况,比较一个函数对象和一个数字,可以看看Python的文档:Python文档:表达式。查看第5.9节,标题为“比较”,里面说:
运算符 <, >, ==, >=, <= 和 != 用来比较两个对象的值。这两个对象不需要是同一种类型。如果都是数字,它们会被转换成一种共同的类型。否则,不同类型的对象总是被认为不相等,并且会以一致但任意的方式进行排序。你可以通过定义一个cmp方法或者像gt这样的丰富比较方法来控制非内置类型对象的比较行为,这在“特殊方法名称”一节中有描述。
(这种不寻常的比较定义是为了简化像排序和 in、not in 运算符这样的操作的定义。未来,不同类型对象的比较规则可能会改变。)
这应该能解释发生了什么以及背后的原因。
顺便说一下,我不太确定在更新版本的Python中会发生什么。
编辑:如果你想知道,Debilski的回答提供了关于Python 3的信息。