Это хорошая идея, чтобы хэшировать класс Python? - PullRequest
5 голосов
/ 26 августа 2009

Например, предположим, что я делаю это:

>>> class foo(object):
...     pass
... 
>>> class bar(foo):
...     pass
... 
>>> some_dict = { foo : 'foo',
... bar : 'bar'}
>>> 
>>> some_dict[bar]
'bar'
>>> some_dict[foo]
'foo'
>>> hash(bar)
165007700
>>> id(bar)
165007700

Исходя из этого, похоже, что класс хешируется в качестве своего идентификатора. Следовательно, не должно быть никакой опасности беспокоиться о, скажем, хешировании bar, когда меняются либо значения foo, либо bar, либо значения хеш-функции, если я изменяю класс.

Надежно ли это поведение, или здесь есть какие-то ошибки?

Ответы [ 2 ]

8 голосов
/ 26 августа 2009

Да, любой объект, который не реализует функцию __hash__(), вернет свой идентификатор после хеширования. От Python Language Reference: Модель данных - базовая настройка :

Пользовательские классы по умолчанию имеют методы __cmp__() и __hash__(); с ними все объекты сравниваются неравно (кроме самих себя) и x.__hash__() возвращает id(x).

Однако, если вы хотите иметь уникальный идентификатор, используйте id, чтобы понять свои намерения. Хеш объекта должен быть комбинацией хэшей его компонентов. См. Ссылку выше для получения более подробной информации.

6 голосов
/ 26 августа 2009

Классы имеют реализации по умолчанию __eq__ и __hash__, которые используют id() для сравнения и вычисления значений хеша соответственно. То есть они сравнивают по идентичности. Основное правило для реализации __hash__ методов заключается в том, что если два объекта сравниваются равными друг другу, они также должны иметь одинаковое значение хеш-функции. Значения хеша можно рассматривать как просто оптимизацию, используемую диктовками и наборами для быстрого поиска одинаковых объектов. Следовательно, если вы измените __eq__ на другой тип тестирования на равенство, вы также должны изменить свою реализацию __hash__, чтобы согласиться с этим выбором.

Классы, которые используют идентичность для сравнения, могут быть свободно видоизменены и использованы в диктах и ​​наборах, потому что их идентичность никогда не меняется. Классы, которые реализуют __eq__ для сравнения по значению и допускают изменение их значений, не могут использоваться в коллекциях хэшей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...