将功能移植到程序的Python 3.1 fork时遇到一个奇怪的错误.我将其缩小为以下假设:
与Python 2.x相比,如果对象具有
__eq__
,则在Python 3.x中
方法是自动取消哈希处理的。
这是真的吗?
这是Python 3.1中发生的事情:
>>> class O(object):
... def __eq__(self, other):
... return 'whatever'
...
>>> o = O()
>>> d = {o: 0}
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
d = {o: 0}
TypeError: unhashable type: 'O'
后续问题是,我该如何解决我的个人问题? 我有一个物体
ChangeTracker
它存储了一个
WeakKeyDictionary
指向多个对象,并为每个对象提供过去某个时间点的酱菜堆的值.每当检入现有对象时,变更跟踪器都会说出其新的泡菜与旧的泡菜是否相同,因此说明对象在此同时是否发生了变化.问题是,现在我什至无法检查给定的对象是否在库中,因为这使它引发有关该对象不可哈希的异常. (因为它有一个
__eq__
方法。)如何解决此问题?
- 2021-1-111 #
- 2021-1-112 #
此段来自http://docs.python.org/3.1/reference/datamodel.html#object. hash
If a class that overrides
__eq__()
需要保留执行__hash__()
从上级班,必须告诉口译员 通过设置__hash__ = <ParentClass>.__hash__
明确 .否则__hash__()
的继承 将会 被阻止,就像__hash__
曾经 明确设置为"无"。在
object.__hash__
上查看Python 3手册 :If a class does not define an
__eq__()
方法,它不应该定义一个__hash__()
操作; if it defines__eq__()
但不是__hash__()
,则其实例将不能用作可散列集合中的项目。强调是我的。
如果您想偷懒,听起来就像您可以定义
__hash__(self)
返回id(self)
:User-defined classes have
__eq__()
和__hash__()
默认情况下的方法; 与他们,所有对象比较不平等(除了自己)和x.__hash__()
返回id(x)
我不是python专家,但是当您定义eq方法时,您还必须定义一个hash方法(计算对象的hash值)是否有意义? ,则哈希机制不会知道它是命中相同的对象还是具有相同哈希值的不同对象.实际上,反之亦然,它可能最终会为您的
__eq__
认为相等的对象计算不同的哈希值 方法。我不知道该哈希函数是什么,
__hash__
也许? :)
相关问题
- python:素因数分解-列表pythonpython3.xprimefactoring2021-01-12 01:25
- windows下适用于Python 3x的OpenCVpythonwindowsopencvpython3.x2021-01-11 22:58
- python:TypeError:worker()接受0个位置参数,但给出了1个pythonpython3.x2021-01-11 22:58
- python:标识符中的字符无效pythonpython3.x2021-01-11 20:56
- 如何在Python 3x中获得类似2x的排序行为?pythonpython3.xsortingpython2.x2021-01-11 07:27
是的,如果您定义
__eq__
,默认为__hash__
(即,哈希对象在内存中的地址)消失了.这很重要,因为散列必须与相等性保持一致:相等的对象需要对散列进行相同的散列。解决方案很简单:只需定义
__hash__
以及定义__eq__