簡體   English   中英

關於可散列對象的解釋需要解釋

[英]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從不重置它們的idname ,則此 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM