將功能移植到程式的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__
方法。)如何解決此問题?
- 3月前1 #
- 3月前2 #
此段来自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__