为什么Python允许可调用对象与数字比较?

2 投票
4 回答
1115 浏览
提问于 2025-04-15 16:15

我上周用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 个回答

3

因为在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']
7

在Python 3中,这个问题已经“修复”了。你可以查看这个链接了解更多信息:http://docs.python.org/3.1/whatsnew/3.0.html#ordering-comparisons

9

这不一定是个错误

首先,得说明一下,这不总是一个错误。

在这个特定的例子中,比较显然是错的。

不过,由于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的信息。

撰写回答