Sin*_*ned 37 python comparison operator-overloading
Python文档清楚地说明了x==y调用x.__eq__(y).然而,似乎在许多情况下,情况正好相反.它记录了何时或为何发生这种情况,以及如何确定我的对象__cmp__或__eq__方法是否会被调用.
编辑:只是为了澄清,我知道这__eq__是在优先考虑__cmp__,但我不清楚为什么y.__eq__(x)被优先调用x.__eq__(y),当后者是文档状态将发生.
>>> class TestCmp(object):
... def __cmp__(self, other):
... print "__cmp__ got called"
... return 0
...
>>> class TestEq(object):
... def __eq__(self, other):
... print "__eq__ got called"
... return True
...
>>> tc = TestCmp()
>>> te = TestEq()
>>>
>>> 1 == tc
__cmp__ got called
True
>>> tc == 1
__cmp__ got called
True
>>>
>>> 1 == te
__eq__ got called
True
>>> te == 1
__eq__ got called
True
>>>
>>> class TestStrCmp(str):
... def __new__(cls, value):
... return str.__new__(cls, value)
...
... def __cmp__(self, other):
... print "__cmp__ got called"
... return 0
...
>>> class TestStrEq(str):
... def __new__(cls, value):
... return str.__new__(cls, value)
...
... def __eq__(self, other):
... print "__eq__ got called"
... return True
...
>>> tsc = TestStrCmp("a")
>>> tse = TestStrEq("a")
>>>
>>> "b" == tsc
False
>>> tsc == "b"
False
>>>
>>> "b" == tse
__eq__ got called
True
>>> tse == "b"
__eq__ got called
True
Run Code Online (Sandbox Code Playgroud)
编辑:从Mark Dickinson的回答和评论中可以看出:
__cmp____eq__是它自己的__rop__,以它的__op__(和类似的__lt__,__ge__等等)__rop__在左对象之前尝试使用右对象__op__这解释了TestStrCmp示例中的行为. TestStrCmp是的一个子类str,但没有实现自己的__eq__这样__eq__的str在这两种情况下的优先级(即tsc == "b"调用b.__eq__(tsc)作为__rop__,因为规则1).
在TestStrEq示例中,tse.__eq__在两个实例中都被调用,因为TestStrEq它是子类,str因此优先调用它.
在TestEq示例中,TestEq实现__eq__并且两次都int不会__eq__被调用(规则1).
但我仍然不明白第一个例子TestCmp. tc不是一个子类,int所以1.__cmp__(tc)应该调用AFAICT ,但不是.
Mar*_*son 31
您缺少通常行为的关键异常:当右侧操作数是左侧操作数的类的子类的实例时,首先调用右侧操作数的特殊方法.
请参阅以下文档:
http://docs.python.org/reference/datamodel.html#coercion-rules
特别是以下两段:
对于对象
x和y,首先x.__op__(y)是尝试.如果没有实现或返回NotImplemented,y.__rop__(x)则尝试.如果还没有实现或返回NotImplemented,则引发TypeError异常.但请参阅以下异常:前一项的异常:如果左操作数是内置类型或新样式类的实例,并且右操作数是该类型或类的正确子类的实例并覆盖基类的
__rop__()方法,则右操作数的__rop__()方法在左操作数的__op__()方法之前尝试.
| 归档时间: |
|
| 查看次数: |
10513 次 |
| 最近记录: |