【转】实习小记-python中可哈希对象是个啥?what is hashable object in python?
【转】实习小记-python中可哈希对象是个啥?what is hashable object in python?
废话不多说直接祭上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,如果某个情况下需要这个类型的哈希值,那么程序将会报错。具体请看下面代码:
>>> class A:
... def __eq__(self, other):
... return True
...
>>> a = A()
>>> import collections
>>> isinstance(a, collections.Hashable) # 发现它不是可哈希对象
False
>>> a.__hash__
>>> a.__hash__()
Traceback (most recent call last):
File "<ipython-input-20-0fddd0562e01>", line 1, in <module>
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__ = <ParentClass>.__hash__.
如果某个重写了__eq__方法的对象需要保留__hash__属性,那么我们需要在类型设置中添加该语句 __hash__ = <ParentClass>.__hash__
请看代码
>>> class A:
... __hash__ = object.__hash__
... def __eq__(self, other):
... return True
...
>>> a = A()
>>> a.__hash__
<method-wrapper '__hash__' of A object at 0x7f21029cfa10>
>>> set([a,2,3])
{<__main__.A object at 0x7f21029cfa10>, 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__这两个方法不能随意动,如果我么需要改写其中一个的话一定要仔细考虑可能的情况,以免出现问题。
【转】实习小记-python中可哈希对象是个啥?what is hashable object in python?的更多相关文章
- 实习小记-python中可哈希对象是个啥?what is hashable object in python?
废话不多说直接祭上python3.3x的文档:(原文链接) object.__hash__(self) Called by built-in function hash() and for opera ...
- 实习小记-python中不可哈希对象设置为可哈希对象
在这篇之前,我又专门翻译过官方python3.3的可哈希对象文档,大家可以先参考一下: 实习小记-python中可哈希对象是个啥?what is hashable object in python? ...
- Python 中的哈希表
Python 中的哈希表:对字典的理解 有没有想过,Python中的字典为什么这么高效稳定.原因是他是建立在hash表上.了解Python中的hash表有助于更好的理解Python,因为Pytho ...
- python中读取json文件报错,TypeError:the Json object must be str, bytes or bytearray,not ‘TextIOWrapper’
利用python中的json读取json文件时,因为错误使用了相应的方法导致报错:TypeError:the Json object must be str, bytes or bytearray,n ...
- 实习小记-python 内置函数__eq__函数引发的探索
乱写__eq__会发生啥?请看代码.. >>> class A: ... def __eq__(self, other): # 不论发生什么,只要有==做比较,就返回True ... ...
- 【转】实习小记-python 内置函数__eq__函数引发的探索
[转]实习小记-python 内置函数__eq__函数引发的探索 乱写__eq__会发生啥?请看代码.. >>> class A: ... def __eq__(self, othe ...
- python中的这些坑,早看早避免。
python中的这些坑,早看早避免. 说一说python中遇到的坑,躲坑看这一篇就够了 传递参数时候不要使用列表 def foo(num,age=[]): age.append(num) print( ...
- Python中操作mysql的pymysql模块详解
Python中操作mysql的pymysql模块详解 前言 pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前pymysql支持python3.x而后者不支持 ...
- [转]关于Python中的yield
在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor). 一.迭代器(iterator) 在Python中,for循环可以用于Python中的任何 ...
随机推荐
- CodeForces160D 最小生成树 + dfs
https://cn.vjudge.net/problem/26727/origin 题目大意: 给一个带权的无向图,保证没有自环和重边. 由于最小生成树不唯一,因此你需要确定每一条边是以下三种情况哪 ...
- python类继承的重写和super
给已经存在的类添加新的行为,继承是非常好的实现方式.但是如果要改变行为呢?比如在Python继承扩展内置类,我们的contact类只允许一个名字和一个邮箱,但是如果要对某些人增加电话号码呢?这里可以通 ...
- Scoring and Modeling—— Underwriting and Loan Approval Process
https://www.fdic.gov/regulations/examinations/credit_card/ch8.html Types of Scoring FICO Scores V ...
- MacOS环境中 python3 部署
MacOS环境中 python3 部署 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.在MacOS安装Python3.6 1>.打开python关于MacOS版本的官方网 ...
- C#设计模式(9)——代理模式
1.代理模式介绍 在软件开发中有时会遇到不能直接使用对象的问题,如我们要使用的对象在进程外,甚至在远程的机器上,但是我们要使用这个对象的功能怎么办呢?代理模式就可以用来解决这个问题.举一个生活中的例子 ...
- Drupal8 入门教程(一)安装部署
一.Drupal简介 Drupal 是使用PHP语言编写的开源内容管理框架(CMF),它由内容管理系统(CMS)和PHP开发框架(Framework)共同构成.连续多年荣获全球最佳CMS大奖,是基于P ...
- C#中的特性(Attributes)
约定: 1.”attribute”和”attributes”均不翻译 2.”property”译为“属性” 3.msdn中的原句不翻译 4.”program entity”译为”语言元素” Attri ...
- 804. Unique Morse Code Words
Description International Morse Code defines a standard encoding where each letter is mapped to a se ...
- Echarts地图悬浮框显示多组series数据以及修改地图大小
1.如何让echarts的地图悬浮框出现多组series数据? 2.如何更改地图默认的大小? <!DOCTYPE html> <html lang="en"> ...
- new
Android支持插件库,可以是由C/C++开发的JNI形式,也可以是由java代码开发的jar形式(也可以是android封包完成的apk文件).加载jar插件的方式可以分为 1.静态加载2.动态加 ...