2013-03-18 46 views
5

虽然标题可以解释为三个问题,但实际问题很容易描述。在Linux系统上,我安装了python 2.7.3,并且想要警告python 3不兼容。因此,我的代码片段(tester.py)看起来像:如何消除相等运算符的python3弃用警告?

#!/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?我想以正确的方式实现相等运算符,而不仅仅是压制警告或类似的东西。

+0

'__eq__'将返回false从'object'继承的对象,除非'A为A' – thkang 2013-03-18 07:39:53

回答

5

documentation页用于Python 3.4:

如果一个类没有定义__eq__()方法不应该限定__hash__()操作要么;如果它定义了__eq__()而不是__hash__(),则其实例将不可用作可哈希集合中的项目。如果一个类定义了可变对象并实现了一个__eq__()方法,那么它不应该实现__hash__(),因为可哈希集合的实现要求密钥的哈希值是不可变的(如果对象的哈希值更改,它将位于错误的哈希桶中)。

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

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

x.__hash__()返回一个适当的值,使得x == y意味着 既该x is yhash(x) == hash(y)

如果您只定义了__eq()__,那么__hash()__设置为返回None。所以你会撞到墙上。

如果您不想为执行__hash()__而烦恼,并且您确定您的对象永远不会被散列,您只需明确声明__hash__ = None负责警告即可。

+0

只是一个虚拟的散列函数基本返回nonesense?或者一个真正返回可用散列值的函数?但是,我需要这样做,从文档片段中不清楚。 – Alex 2013-03-18 07:11:07

+0

同样,从同一页面:'__hash __()'应该返回一个整数。唯一需要的属性是比较相等的对象具有相同的散列值 – 2013-03-18 07:13:39

+0

阅读关于散列和eq函数的描述 - 它们表示清楚。 – 2013-03-18 07:14:25

0

亚历克斯:python的-3选项警告你一个潜在的问题;它不知道你没有在集合中使用MyClass的实例或在映射中作为键,所以它警告说,如果你是的话,你可能依赖的东西是行不通的。如果您不以这种方式使用MyClass,请忽略该警告。这是一个愚蠢的工具来帮助你捕捉潜在的问题;最后,你需要具备真正的情报来确定哪些警告真的很重要。

如果你真的关心抑制警告 - 或者更确切地说,如果一个类是可变的,你想确保它是成套或在任何映射按键使用不 - 简单赋值__hash__ = None(正如Sudipta指出的那样)在班级体内应该为你做。由于None不可调用,这使得实例不可哈希。

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