【发布时间】:2015-03-05 20:46:33
【问题描述】:
这个问题是由一个失败的测试引起的,该测试拒绝在本地失败,并且只会在我们的 CI 服务器上失败。
结果是无意中进行了一些相当狡猾的对象比较。
我现在很好奇为什么同一 Python 版本 (2.7.9) 的两个安装之间的行为如此不同。
这个测试用例可能会进一步简化,但这就是我得到的:
import operator
class Thing(dict):
def __int__(self, number):
return self['number']
def __gt__(self, other):
return self['number'] > other
thing = Thing({'number': 2})
for o in [
operator.lt,
operator.le,
operator.eq,
operator.ne,
operator.ge,
operator.gt]:
print o
print o(0.01, thing)
print o(thing, 0.01)
而在本地运行的结果是:
<built-in function lt>
True
False
<built-in function le>
True
False
<built-in function eq>
False
False
<built-in function ne>
True
True
<built-in function ge>
False
True
<built-in function gt>
False
True
但在 Travis CI 服务器上是:
<built-in function lt>
True
True
<built-in function le>
False
True
<built-in function eq>
False
False
<built-in function ne>
True
True
<built-in function ge>
True
False
<built-in function gt>
True
True
Python 回退到什么样的比较行为,为什么它会在相同版本的两个安装中表现出如此不同的行为?
我最初的想法是某种基于id 的比较,但从查看id 的值来看,它们与比较结果完全不相关。
更新:
这种不同的行为只发生在类继承自dict 时。当它从 object 继承时,比较在两种安装上的行为相同,并给出与上述本地结果相同的结果。
更新 2:
我刚刚发现只使用 __int__ 和 __gt__ 方法可以进一步简化测试用例,但是如果我删除其中任何一个方法,那么奇怪的行为就会消失。
【问题讨论】:
-
一个有趣的问题!如果您使用仅继承自
object而不是dict的类,您能否重现该行为?我还没有弄清楚发生了什么,但要注意的一件事是dict定义了一些您的类没有的比较操作(实际上它定义了所有普通的不等式比较)。 -
在我的机器上尝试这个 le,ne 和 ge 不调用类中定义的函数。这对我来说似乎很有趣,因为您的服务器和本地计算机上的答案不同,但据我了解,如果只使用内置函数,不同的答案......很奇怪?
-
我刚才也在想同样的事情,发现只有从
dict继承时才会发生这种行为。我已经简化了上面的测试用例。从object继承时,它们在两种安装中的行为相同。 -
functools.total_ordering--> "填充缺失排序方法的类装饰器"...但是dict中没有缺失排序方法。 -
@tdelaney,这很好!但是什么可以解释两个安装之间的行为差异呢?
标签: python comparison-operators