python:聊一聊 ==和魔法方法__eq__之间的关系

摘要

  环境: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__()或者实现关系运算符的别的魔法方法来改变这一窘境。
    • 比如在设计数据筛选或排序的时候,筛选或排序规则有很多种,传入后台的参数不一定会全包括了,这时候排序的参数体就是一个不定长的了,于是就可以设计一个列表存入所有通过关系运算符返回的条件,然后通过解包(*)的方式进行传参。
发布了55 篇原创文章 · 获赞 3 · 访问量 2733

猜你喜欢

转载自blog.csdn.net/rusi__/article/details/103214931