我正在嘗試爲字符串創建一個自定義哈希函數。我想按字符頻率按重量對字符串進行哈希處理。所以hi
和ih
將產生相同的散列。我可以覆蓋__hash__
嗎?Python重寫字符串__hash__
或者正在創建一個包裝類,包含字符串並覆蓋__hash__
和__eq__
唯一的方法?
我正在嘗試爲字符串創建一個自定義哈希函數。我想按字符頻率按重量對字符串進行哈希處理。所以hi
和ih
將產生相同的散列。我可以覆蓋__hash__
嗎?Python重寫字符串__hash__
或者正在創建一個包裝類,包含字符串並覆蓋__hash__
和__eq__
唯一的方法?
您希望派生類型具有不同的相等語義。通常採用的方法是定義平等是如何工作的,然後根據派生於此的結構構建哈希方法,因爲哈希值必須與平等相符。這可能是:
import collections
class FrequencyString(str):
@property
def normalized(self):
try:
return self._normalized
except AttributeError:
self._normalized = normalized = ''.join(sorted(collections.Counter(self).elements()))
return normalized
def __eq__(self, other):
return self.normalized == other.normalized
def __hash__(self):
return hash(self.normalized)
假設我創建了一個可以返回散列的自由函數。我將如何在返回的散列位置插入該密鑰? dict = {},dict [5] = value'在位置5插入「值」,還是按'5'? – darksky
將值放在字典*中*意味着改變平等語義,這是正確的方法。您可以交替地將封裝器構造爲一個信封,並將原始字符串作爲實例屬性。 – SingleNegationElimination
你的假設是正確的,你不能重寫Python中的基類。雖然可以重寫str()
將會執行的操作,但它不適用於字符串文字。
如果你是,如果你想創建寫在Python 2.2看看UserString
類代碼自己:http://docs.python.org/2/library/userdict.html#module-UserString
否則,你可以簡單地繼承str
或unicode
在你的情況簡單地覆蓋如果您想將其用作字典密鑰,則方法已足夠。但是,如果你看的比較比你將不得不覆蓋__eq__
或__cmp__
您可以從str
繼承,但因爲這些是不可變的,你必須繼承他們的方式略有不同。很可能你會想從現有的字符串中創建新的字符串,所以你也必須重寫__new__
方法。您可能還需要添加額外的特殊方法來打敗Python所做的優化。
這是一個子類化內置str
,mapstr對象的示例,該對象允許在表單中輕鬆替換佔位符。
我會使用包裝類。它很好,很明確,並且不會因爲冒充字符串而導致混淆,而完全不同。 – millimoose
@millimoose好點 – darksky
將'str'和'custom_str'混合到一個使用散列作爲鍵的容器中可能會很有趣:) –