摘要
环境:python3.65
有时候我们会发现,有些代码中进行判等(==)操作的时候,返回的竟然不是True或者False,这是为什么呢?
实际上这是因为,该对象所对应的类,重载了__eq__方法的缘故。
首先:看一下下面的代码片(ipython3):
In [6]: 1==1
Out[6]: True
In [7]: 1.__eq__(1)
File "<ipython-input-7-5a7ad3350996>", line 1
1.__eq__(1)
^
SyntaxError: invalid syntax
In [8]: a=1
In [9]: a.__eq__(1)
Out[9]: True
现在是不是感觉一目了然了?
但是,是不是发现1.__eq__(1)
返回的是一个异常?这是为什么呢?我进行了以下测试:
- 通过dir(1)和dir(a)发现两者都具备__eq__方法;
- 这样就说明:1中实现的__eq__方法和a中的__eq__方法是不一样的。为什么会这样?要知道:
1和a最大的区别是:1不是变量名。
然后:再看一下下面的代码片(ipython2):
In [9]: a.__eq__(1)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-9-4038534679a9> in <module>()
----> 1 a.__eq__(1)
AttributeError: 'int' object has no attribute '__eq__'
这里会发现a.__eq__(1)
也会报错了,这是为什么?我进行了以下测试:
- 通过dir(a)发现a确实没有__eq__方法
- 但是我又发现了,除了整型,甚至浮点型都有__eq__方法:
In [22]: a=1.0 In [23]: a.__eq__(1.0) Out[23]: True
。 - 于是我不想深究了,毕竟python2已经要被更迭了,而且,就算我深究也没啥意义。
补充
is和==的区别:前者判断内存日志是否一致,后者只是比较值关系。
总结
- 应用场景:当你需要将一系列的条件通过对象或者表达式变现出来的时候,bool肯定不能满足你的需求,所以你可以尝试重写__eq__()或者实现关系运算符的别的魔法方法来改变这一窘境。
- 比如在设计数据筛选或排序的时候,筛选或排序规则有很多种,传入后台的参数不一定会全包括了,这时候排序的参数体就是一个不定长的了,于是就可以设计一个列表存入所有通过关系运算符返回的条件,然后通过解包(*)的方式进行传参。