我有以下代码:
a = str('5')
b = int(5)
a == b
# False
但是,如果我创建int
的子类,并重新实现__cmp__
:
class A(int):
def __cmp__(self, other):
return super(A, self).__cmp__(other)
a = str('5')
b = A(5)
a == b
# TypeError: A.__cmp__(x,y) requires y to be a 'A', not a 'str'
为什么这两个不同? python运行时是否捕获int.__cmp__()
抛出的TypeError,并将其解释为False
值?有人能指出我在2.x cpython源代码中显示这是如何工作的吗?
答案 0 :(得分:5)
关于这一点,文档并不完全明确,但请参阅here:
如果两者都是数字,则将它们转换为通用类型。否则,不同类型的对象总是比较不相等,并且一致但是任意地排序。您可以通过定义
__cmp__
方法或丰富的比较方法(如__gt__
)来控制非内置类型对象的比较行为,如特殊方法名称一节所述。
这(特别是“不同类型的对象”和“非内置类型的对象”之间的隐式对比)表明,内置类型会跳过实际调用比较方法的正常过程:如果您尝试比较两个不同(和非数字)内置类型的对象,它只是短路到自动False。
答案 1 :(得分:3)
a == b
的比较决策树看起来像:
a.__cmp__(b)
a
检查b
是否合适类型b
是合适的类型,请返回-1
,0
或+1
b
不是,请返回NotImplented
-1
,0
或+1
返回,则python已完成;否则b.__cmp__(a)
b
检查a
是否合适类型a
是合适的类型,请返回-1
,0
或+1
a
不是,请返回NotImplemented
-1
,0
或+1
返回,则python已完成;否则False
不是一个确切的答案,但希望它有所帮助。
答案 2 :(得分:-2)
如果我理解你的问题,你需要这样的东西:
>>> class A(int):
... def __cmp__(self, other):
... return super(A, self).__cmp__(A(other)) # <--- A(other) instead of other
...
>>> a = str('5')
>>> b = A(5)
>>> a == b
True
<强>更新强>
关于2.x cpython源代码,你可以在函数typeobject.c
的{{1}}中找到这个结果的原因,它实际检查了两件事:给定比较函数是wrap_cmpfunc
和{{ 1}}是func
的子类型。
other