python中可哈希是什么意思_实习小记-python中可哈希对象是个啥?what is hashable object in python?...

可哈希对象是指实现了`__hash__()`方法的Python对象,它们在比较时如果相等则必须具有相同的哈希值。如果类定义了`__eq__()`但未定义`__hash__()`,其实例无法在哈希集合中使用。默认情况下,用户定义的类具有`__eq__()`和`__hash__()`,所有实例比较不等,除非是同一对象。重写`__eq__()`而不定义`__hash__()`会导致`__hash__`被隐式设为None,使得实例不可哈希。
摘要由CSDN通过智能技术生成

废话不多说直接祭上python3.3x的文档:(原文链接)

object.__hash__(self)

Called by built-in function hash() and for operations on members of hashed collections including set, frozenset, and dict. __hash__() should return an integer. The only required property is that objects which compare equal have the same hash value; it is advised to somehow mix together (e.g. using exclusive or) the hash values for the components of the object that also play a part in comparison of objects.

可哈希对象是对象拥有__hash__(self)内置函数的对象。对于可哈希的对象执行这个函数将会返回一个整数。可哈希对象判断相等的唯一条件就是两者 的哈希值相等。如果我们的对象有多个属性值,我们会使用一种方法(比方说逻辑运算异或)来将其属性值结合在一起做比较。(如果不对,麻烦一定告诉我,谢谢!)

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).

如果一个类型定义没有定义__eq__()函数,那么它也不应该定义__hash__();因为如果它定义了__eq__而没有定义__hash__,那么它的实例在某个可哈希集合中将会无效(比方说在字典/集合这类类型中)。如果一个类型定义了一个可变对象而且定义了__eq__方法,那么它不应该去定义__hash__方法,因为在哈希集合中要求其中元素的哈希值是不变的(如果某个对象实例的哈希值发生了改变,那么他将会到错误的哈希表中。。)。

User-defined classes have __eq__() and __hash__() methods by default; with them, all objects compare unequal (except with themselves) and x.__hash__() returns an appropriate value such that x == y implies both that x is y and hash(x) == hash(y).

用户定义的类中都有默认的__eq__和__hash__方法;有了它,所有的对象实例都是不等的(除非是自己和自己比较),在做 x == y比较时是和这个等价的 hash(x) == hash(y)。

A class that overrides __eq__() and does not define __hash__() will have its __hash__() implicitly set to None. When the __hash__() method of a class is None, instances of the class will raise an appropriate TypeError when a program attempts to retrieve their hash value, and will also be correctly identified as unhashable when checking isinstance(obj, collections.Hashable).

这句话的意思是,如果我们定义了一个类型,该类型只定义了__eq__而没有定义__hash__的话,那么他的__hash__()会隐式的设置为None,如果某个情况下需要这个类型的哈希值,那么程序将会报错。具体请看下面代码:

>>> classA:

...def __eq__(self, other):

...returnTrue

...>>> a =A()>>> importcollections>>> isinstance(a, collections.Hashable) #发现它不是可哈希对象

False>>> a.__hash__

>>> a.__hash__()

Traceback (most recent call last):

File"", line 1, in a.__hash__()

TypeError:'NoneType' object is not callable

然后往下看文档

If a class that overrides __eq__() needs to retain the implementation of __hash__() from a parent class, the interpreter must be told this explicitly by setting __hash__ = .__hash__.

如果某个重写了__eq__方法的对象需要保留__hash__属性,那么我们需要在类型设置中添加该语句 __hash__ = .__hash__

请看代码

>>> classA:

...__hash__ = object.__hash__...def __eq__(self, other):

...returnTrue

...>>> a =A()>>> a.__hash__

>>> set([a,2,3])

{<__main__.a object at>, 2, 3}

If a class that does not override __eq__() wishes to suppress hash support, it should include __hash__ = None in the class definition. A class which defines its own __hash__() that explicitly raises a TypeError would be incorrectly identified as hashable by an isinstance(obj, collections.Hashable) call.

如果某个类型定义需要将__hash__属性删掉,那么我们可以在类变量中这样写 __hash__ = None

看完了还是有点小激动的,今天因为一个偶然原因,接触到了这么多的python知识。真的是相当高兴阿!

然而我也发现__eq__ __hash__这两个方法不能随意动,如果我么需要改写其中一个的话一定要仔细考虑可能的情况,以免出现问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值