我有以下代码:
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源码中显示了这是如何工作的吗?
发布于 2012-09-18 02:40:21
文档在这一点上并不是完全明确的,但请参阅here
如果两者都是数字,则将它们转换为通用类型。否则,不同类型的对象总是比较不相等,并且排序一致但任意。可以通过定义
__cmp__方法或丰富的比较方法(如__gt__)来控制非内置类型的对象的比较行为,如特殊方法名称一节中所述。
这(特别是“不同类型的对象”和“非内置类型的对象”之间的隐式对比表明,对于内置类型,实际调用比较方法的正常过程被跳过了:如果您尝试比较两个不同(和非数字)内置类型的对象,它只会缩短为自动False。
发布于 2012-09-18 02:49:14
a == b的比较决策树如下所示:
如果
a是适当的类型,则返回+1NotImplented>D16>不是,则返回
a.__cmp__(b) b
b是适当的类型,则返回-1、0
-1、0或+1,则python完成;否则a是否为适当的类型。如果D38是适当的类型,则返回D39、D40或+1NotImplemented,则返回python。如果返回的是NotImplented,则a检查a是否为适当的类型。
-1、0或+1,则完成;否则不是一个确切的答案,但希望它能有所帮助。
发布于 2012-09-18 02:17:57
如果我没理解错你的问题,你需要这样的东西:
>>> 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.xcpython源代码,你可以在函数wrap_cmpfunc的typeobject.c中找到这个结果的原因,它实际上检查了两件事:给定的比较函数是一个func,other是self的子类型。
if (Py_TYPE(other)->tp_compare != func &&
!PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) {
// ....
}https://stackoverflow.com/questions/12464913
复制相似问题