How to eliminate a python3 deprecation warning for the equality operator?

时光总嘲笑我的痴心妄想 提交于 2020-01-14 09:52:20

问题


Although the title can be interpreted as three questions, the actual problem is simple to describe. On a Linux system I have python 2.7.3 installed, and want to be warned about python 3 incompatibilities. Therefore, my code snippet (tester.py) looks like:

#!/usr/bin/python -3

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

When I execute this code snippet (thought to be only to show the problem, not an actual piece of code I am using in my project) as

./tester.py

I get the following deprecation warning:

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

My question: How do I change this code snippet to get rid of the warning, i.e. to make it compatible to version 3? I want to implement the equality operator in the correct way, not just suppressing the warning or something similar.


回答1:


From the documentation page for Python 3.4:

If a class does not define an __eq__() method it should not define a __hash__() operation either; if it defines __eq__() but not __hash__(), its instances will not be usable as items in hashable collections. If a class defines mutable objects and implements an __eq__() method, it should not implement __hash__(), since the implementation of hashable collections requires that a key’s hash value is immutable (if the object’s hash value changes, it will be in the wrong hash bucket).

Basically, you need to define a __hash()__ function.

The problem is that for user-defined classes, the __eq()__ and __hash()__ functions are automatically defined.

x.__hash__() returns an appropriate value such that x == y implies both that x is y and hash(x) == hash(y).

If you define just the __eq()__, then __hash()__ is set to return None. So you will hit the wall.

The simpler way out if you don't want to bother about implementing the __hash()__ and you know for certain that your object will never be hashed, you just explicitly declare __hash__ = None which takes care of the warning.




回答2:


Alex: python's -3 option is warning you about a potential problem; it doesn't know that you aren't using instances of MyClass in sets or as keys in mappings, so it warns that something that you might have been relying on wouldn't work, if you were. If you aren't using MyClass that way, just ignore the warning. It's a dumb tool to help you catch potential problems; in the end, you're expected to be the one with the actual intelligence to work out which warnings actually matter.

If you really care about suppressing the warning - or, indeed, if a class is mutable and you want to make sure it isn't used in sets or as the key in any mapping - the simple assignment __hash__ = None (as Sudipta pointed out) in the class body shall do that for you. Since None isn't callable, this makes instances non-hashable.

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


来源:https://stackoverflow.com/questions/15471333/how-to-eliminate-a-python3-deprecation-warning-for-the-equality-operator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!