当一个对象可以等同于不同类型的对象时如何定义__hash__? [英] How to define __hash__ when an object can be equal to different kind of objects?

查看:101
本文介绍了当一个对象可以等同于不同类型的对象时如何定义__hash__?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Python doscumentation中,我们可以阅读关于 __ hash __ 函数:


只有必需的属性是比较相等的对象具有相同的散列值

我有一个可以相等的对象到另一个相同类型的对象或字符串:

$ p $ class MyClass:
def __eq __(self,other) :
如果isinstance(other,str):
返回self.x == other
if isinstance(other,MyClass):
return id(self)== id )
return False

拥有 __ eq __ 函数,我如何定义一个有效的 __ hash __ 函数?


$ b 警告:在这里, MyClass()对象是可变的, self.x 可以改变!

解决方案

您无法定义一致的散列。首先,你的类没有一致地定义 __ eq __ ;不保证如果 x == y y == z ,那么 x == z 。其次,你的对象是可变的。如果一个类定义了可变对象并实现了一个 __ cmp__ () __ eq __()方法,它不应该实现 __ hash __(),因为可散列集合实现要求对象的散列值是不可变的(如果对象的散列值发生变化,它将位于错误的散列桶中)。



< ==

  x = MyClass(' foo')
y ='foo'
z = MyClass('foo')

x == y#True
y == z#True
x == z#False


In Python doscumentation, we can read about __hash__ function :

The only required property is that objects which compare equal have the same hash value.

I have an object which can be equal to other object of the same type, or to strings:

class MyClass:
    def __eq__(self, other):
        if isinstance(other, str):
            return self.x == other
        if isinstance(other, MyClass):
            return id(self) == id(other)
        return False

Having this __eq__ function, how could I define a valid __hash__ function ?

Warning: Here, MyClass() objects are mutable, and self.x could change !

解决方案

You can't define a consistent hash. First, your class does not define __eq__ consistently; it is not guaranteed that if x == y and y == z, then x == z. Second, your object is mutable. In Python, mutable objects are not supposed to be hashable.

If a class defines mutable objects and implements a __cmp__() or __eq__() method, it should not implement __hash__(), since hashable collection implementations require that a object’s hash value is immutable (if the object’s hash value changes, it will be in the wrong hash bucket).

Example of broken ==:

x = MyClass('foo')
y = 'foo'
z = MyClass('foo')

x == y # True
y == z # True
x == z # False

这篇关于当一个对象可以等同于不同类型的对象时如何定义__hash__?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆