简体   繁体   English

如何在Python中有选择地覆盖'=='行为?

[英]How to selectively override '==' behaviour in Python?

Environment: Python 2.7 (It just might have something to do with this.) 环境:Python 2.7(它可能与此有关。)

First I understand the '==' is implemented as following ( source ): 首先我理解'=='实现如下( 来源 ):

  1. if 如果
    • type(b) is a new-style class, type(b)是一个新式的类,
    • type(b) is a subclass of type(a) type(b)是的子类type(a)
    • type(b) has overridden __eq__ type(b)已覆盖__eq__

then the result is b.__eq__(a) 然后结果是b.__eq__(a)

  1. If 如果
    • type(a) has overridden __eq__ (that is, type(a).__eq__ isn't object.__eq__ ) type(a)已重写__eq__ (即, type(a).__eq__object.__eq__

then the result is a.__eq__(b) 然后结果是a.__eq__(b)

  1. If 如果
    • type(b) has overridden __eq__ type(b)已覆盖__eq__

then the result is b.__eq__(a) . 然后结果是b.__eq__(a)

  1. If none of the above are the case, repeats the process above, but looking for __cmp__ . 如果不是上述情况,请重复上述过程,但要查找__cmp__ If it exists, the objects are equal if it returns zero. 如果存在,则对象返回零时相等。

  2. As a final fallback, Python calls object.__eq__(a, b) , which is just testing if a and b are the same object. 作为最后的回退,Python调用object.__eq__(a, b)object.__eq__(a, b)测试a和b是否是同一个对象。

.

Now I want to override __eq__ of an object, but falls back to the mechanism above when object has no custom __eq__ defined. 现在我想覆盖一个对象的__eq__ ,但是当对象没有定义自定义__eq__时,我会回到上面的机制。 How to achieve this? 怎么做到这一点?

I can't just save the original __eq__ method because '==' actually involves a complex mechanism described above. 我不能只保存原始的__eq__方法,因为'=='实际上涉及上面描述的复杂机制。

Example Code (with target not achieved): 示例代码(未达到目标):

class A(object):
    def __eq__(self, other):
        try:
            self.___eq___
            return self.___eq___(other)
        except AttributeError:
            # trying to save default behaviour (Goal)

def custom_eq_bound_method(self, other):
    return True

# overriding __eq__
a1 = A()
a1.___eq___ = MethodType(custom_eq_bound_method, a1, A)

# not overriding __eq__
a2 = A()

# comparing a1 == a2 in business logic....

I'm sure you've asked this before and had it answered, but it seems what you are looking for is to have the class to try to defer to your own alias for __eq__ since this method cannot be overridden at the instance level. 我确定你之前已经问过这个并且已经得到了答案,但是你正在寻找的是让类试图推迟你自己的__eq__别名,因为这个方法不能在实例级别被覆盖。

from types import MethodType
class A(object):
    def __eq__(self, other):
        try:
            self._eq
            return self._eq(other)        # defer to _eq
        except AttributeError:
            return super().__eq__(other)  # Here is the default behaviour

def custom_eq_bound_method(self, other):
    return True

a1 = A()
a2 = A()
a3 = A()

print(a1==a2)
print(a1==a3)
print(a2==a3)

a1._eq = MethodType(custom_eq_bound_method, a1)
print('After override')

print(a1==a2)
print(a1==a3)
print(a2==a3)

Output: 输出:

False
False
False
After override
True
True
False

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM