python - 如何选择性地覆盖 Python 中的“==”行为?
问题描述
环境:Python 2.7(可能与此有关。)
首先,我了解“==”的实现方式如下(来源):
- 如果
type(b)
是新式班,type(b)
是一个子类type(a)
type(b)
已覆盖__eq__
那么结果是
b.__eq__(a)
- 如果
type(a)
已被覆盖__eq__
(即type(a).__eq__
is notobject.__eq__
)那么结果是
a.__eq__(b)
- 如果
type(b)
已覆盖__eq__
那么结果是
b.__eq__(a)
。
如果以上都不是,重复上述过程,但寻找
__cmp__
. 如果存在,则如果返回零,则对象相等。作为最后的后备,Python 调用
object.__eq__(a, b)
,它只是测试 a 和 b 是否是同一个对象。
.
现在我想覆盖__eq__
一个对象,但是当对象没有自定义定义时,我会退回到上面的机制__eq__
。如何做到这一点?
我不能只保存原始__eq__
方法,因为 '==' 实际上涉及上述复杂机制。
示例代码(未达到目标):
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....
解决方案
我敢肯定你之前已经问过这个问题并得到了回答,但似乎你正在寻找的是让类尝试推迟到你自己的别名,__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)
输出:
False
False
False
After override
True
True
False
推荐阅读
- sql - 从 Presto 中的 JSON 数组中提取值
- oracle - 计算一条语句或忽略它 PLSQL
- python - 如何比较列子集上两个数据帧之间的所有行匹配?
- django - Django,谷歌应用引擎,存储桶没有“访问控制允许来源”
- api - 使用 Apache Superset API 提供数据集
- python - 如何在python中同时使用封装和继承
- html - iOS Safari HTML5 音频播放 - 锁定屏幕下一个/上一个按钮已禁用
- asp.net-mvc - Fiddler 捕获 Web.API
- python - 如何识别是否单击了 Angular 切换开关切换?
- php - 如何显示此字符串中每个字母的出现次数