[英]Explanation needed regarding explanation of hashable objects
Mark Ransom在 SO 中回答了關於哈希的 SO 問題:
[...] 如果 object 的 hash 值在其生命周期內永遠不會改變,則它是可散列的。 所以按照官方的定義,任何可變的東西都不能被哈希,即使它有一個
__hash__()
function。 我關於這兩個要求都是必要的陳述是不真實的,因為可散列已經意味着要求是不可變的。
我想確保我做對了——即使作為非母語人士——所以如果我做錯了,我希望有人糾正我。
假設這個 class
class Author(object):
def __init__(self, id, name, age):
self.id = id
self.name = name
self.age = age
def __eq__(self, other):
return self.id==other.id\
and self.name==other.name
def __hash__(self):
return hash(('id', self.id,
'name', self.name))
我了解, __eq__
允許我將此 class 的對象與==
運算符進行比較。 從 Marks 的回答中我了解到,即使我的 object peter = Author(1, "Peter", 33)
有一個__hash__
它也不是可散列的,因為我可能會做類似peter.age = 43
的事情,這意味着它不是不可變的。 所以我的 class Author
的對象是不可散列的,因此不能用作字典中的鍵? 我是對的還是看起來我需要更多解釋? :-)
如果您promise從不重置它們的id
或name
,則此 class 的實例是可散列的。 您不能保證這些屬性永遠不會被重置,根據 Python 原則“我們都是在這里同意的成年人” ,但是提供重置__hash__
依賴的屬性的方法將是非常糟糕的風格。
例如,如果您在Author
實例上提供set_name
方法,但沒有set_id
,則 class 的客戶端可以合理地假定__hash__
僅在id
上運行。
如果您想讓Author
的客戶清楚他們不應該重置某些屬性,您可以通過在其名稱前添加一個_
來將其私有化。 如果您仍然想使用其通用名稱提供對屬性的(只讀)訪問,您可以將其設為屬性:
class Author(object):
def __init__(self, id, name, age):
self._id = id
self._name = name
self.age = age # ages tend to change, so mutable
id = property(lambda self: self._id)
name = property(lambda self: self._name)
def __eq__(self, other):
return self.id==other.id\
and self.name==other.name
def __hash__(self):
return hash(('id', self.id,
'name', self.name))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.