Переопределение хэша строки 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 объект, который позволяет легко заменять заполнители в формы.