如何消除相等运算符的python3弃用警告?

时间:2013-03-18 07:04:15

标签: python python-2.7 deprecated

虽然标题可以解释为三个问题,但实际问题很容易描述。在Linux系统上我安装了python 2.7.3,并希望收到有关python 3不兼容性的警告。因此,我的代码段(tester.py)如下所示:

#!/usr/bin/python -3

class MyClass(object):    
    def __eq__(self, other):
        return False

当我执行此代码片段(被认为只是为了显示问题,而不是我在项目中使用的实际代码段)时

./tester.py

我收到以下弃用警告:

./tester.py:3: DeprecationWarning: Overriding __eq__ blocks inheritance of __hash__ in 3.x
  class MyClass(object):

我的问题:如何更改此代码段以消除警告,即使其与版本3兼容?我想以正确的方式实现相等运算符,而不仅仅是抑制警告或类似的东西。

2 个答案:

答案 0 :(得分:5)

从Python 3.4的documentation页面:

  

如果某个类没有定义__eq__()方法,则它也不应定义__hash__()操作;如果它定义__eq__()但不定义__hash__(),则其实例将不能用作可散列集合中的项目。如果一个类定义了可变对象并实现了__eq__()方法,那么它不应该实现__hash__(),因为hashable集合的实现要求键的哈希值是不可变的(如果对象的哈希值发生变化,它将会在错误的哈希桶中。)

基本上,您需要定义__hash()__函数。

问题是对于用户定义的类,会自动定义__eq()____hash()__函数。

  

x.__hash__()返回x == y暗示的适当值   x is yhash(x) == hash(y)

如果仅定义__eq()__,则__hash()__设置为返回None。所以你会碰壁。

如果你不想打扰实现__hash()__并且你肯定知道你的对象永远不会被散列,那么更简单的方法就是你明确声明__hash__ = None来处理警告。

答案 1 :(得分:0)

Alex:python' s选项警告你一个潜在的问题;它并不知道你没有在集合中使用MyClass的实例或者在映射中使用MyClass的实例,所以它会警告你可能依赖的某些东西是不可行的,如果你的话。如果您没有这样使用MyClass,请忽略该警告。这是一个帮助你发现潜在问题的愚蠢工具;最后,你有望成为具有实际情报的人,以确定哪些警告确实很重要。

如果你真的关心抑制警告 - 或者,确实,如果一个类是可变的,你想确保不是在集合中使用或作为任何映射中的键 - 类体中的简单赋值__hash__ = None(正如Sudipta指出的那样)应该为你做。由于None不可调用,这使得实例不可清除。

    class MyClass (object):
        def __eq__(self, other): return self is other
        __hash__ = None