Переопределение хэша строки Python
Я пытаюсь создать пользовательскую функцию хэширования для строк. Я хочу хэшировать строки по их частоте символов по весу. Так что hi
и ih
даст тот же хэш. Могу ли я переопределить __hash__
?
или создает класс-оболочку, который содержит строку и переопределяет __hash__
и __eq__
единственный способ?
3 ответов
требуется производный тип с различной семантикой равенства. Обычно используемый подход заключается в том, чтобы определить, как работает равенство, а затем построить хэш-метод из структур, полученных там, поскольку необходимо, чтобы хэш соглашался с равенством. Это может быть:
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)
ваше предположение верно, вы не можете переопределить базовые классы в Python. Хотя может, конечно, переопределить то, что str()
будет сделано, это не будет работать для строковых литералов.
если вы пишете код для pre-python 2.2, посмотрите на
вы можете наследовать от str
, но так как они являются неизменными, вы должны подкласс их немного по-другому. Скорее всего, вы захотите создать новые из существующих строк, поэтому вы также должны переопределить __new__
метод. Возможно, Вам также придется использовать дополнительные специальные методы, чтобы победить оптимизацию, которую делает Python.
вот пример подкласса встроенного str
, the mapstr объект, который позволяет легко заменять заполнители в формы.