Типы, которые определяют '__ eq __', unhashable?

По моему опыту, это относится к барьер памяти , который является инструкцией (явный или неявный) для синхронизации доступа к памяти между несколькими потоками.

проблема происходит в комбинации современных агрессивных компиляторов (у них есть удивительная свобода переупорядочить инструкции, но обычно не знать ничего из Ваших потоков), и современные многоядерные центральные процессоры.

А хорошее введение в проблему" , 'Перепроверяемая Блокировка Повреждается' Объявление ". Для многих это был призыв к действию это там быть драконами.

Неявные полные барьеры памяти обычно включаются в стандартные программы синхронизации потока платформы, которые покрывают ядро его. Однако для программирования без блокировок и реализации пользовательских, легких шаблонов синхронизации, Вам часто нужен просто барьер, или даже односторонний барьер только.

66
задан Alexey 25 February 2018 в 11:13
поделиться

4 ответа

Да, если вы определите __ eq __ , значение по умолчанию __ hash __ (а именно, хеширование адреса объекта в памяти) исчезнет. Это важно, потому что хеширование должно согласовываться с равенством: одинаковые объекты должны хешировать одинаково.

Решение прост: просто определите __ hash __ вместе с определением __ eq __ .

]
65
ответ дан 24 November 2019 в 15:05
поделиться

Этот абзац из http://docs.python.org/3.1/reference/datamodel.html#object. hash

Если класс, который переопределяет __ eq __ () необходимо сохранить реализацию __ hash __ () из родительского класса, это необходимо сообщить интерпретатору. явно путем установки __ hash__ = .__ hash __ . В противном случае наследование __ hash __ () будет заблокирован, как если бы __ hash __ был явно установлено в None.

22
ответ дан 24 November 2019 в 15:05
поделиться

См. Руководство Python 3 по объекту .__ hash __ :

Если класс не определяет метод __ eq __ () , он не должен определять операция __ hash __ () ; , если он определяет __ eq __ () , но не __ hash __ () , его экземпляры не будут использоваться в качестве элементов в хэшируемых коллекциях.

Акцент мой.

Если вы хотите быть ленивым, похоже, вы можете просто определить __ hash __ (self) , чтобы вернуть id (self) :

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

3
ответ дан 24 November 2019 в 15:05
поделиться

Я не эксперт по Python, но разве не имеет смысла, что когда вы определяете метод eq, у вас также есть также определить хэш-метод (который вычисляет хеш-значение для объекта). В противном случае механизм хеширования не узнает, попал ли он в тот же объект или другой объект с таким же хеш-значением. На самом деле, все наоборот, это, вероятно, в конечном итоге приведет к вычислению разных хеш-значений для объектов, считающихся равными по вашему методу __ eq __ .

Я понятия не имею, что вызывается эта хеш-функция, __ hash __ возможно? :)

механизм хеширования не узнает, попал ли он в тот же объект или другой объект с тем же хеш-значением. На самом деле, все наоборот, это, вероятно, в конечном итоге приведет к вычислению разных хеш-значений для объектов, считающихся равными по вашему методу __ eq __ .

Я понятия не имею, что вызывается эта хеш-функция, __ hash __ возможно? :)

механизм хеширования не узнает, попал ли он в тот же объект или другой объект с тем же хеш-значением. На самом деле, все наоборот, это, вероятно, в конечном итоге приведет к вычислению разных хеш-значений для объектов, считающихся равными по вашему методу __ eq __ .

Я понятия не имею, что вызывается эта хеш-функция, __ hash __ возможно? :)

1
ответ дан 24 November 2019 в 15:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: