Запретить автоматическую хэш-функцию для изменяемых классов
Python допускает значения хеш-функции только для неизменяемых объектов. Например,
hash((1,2,3))
работает, но
hash([1,2,3])
поднимает TypeError: unhashable type: 'list'
, Смотрите документацию по Python. Однако, когда я оборачиваю класс C++ в Boost.Python через обычный boost::python::class_<>
Функция, каждый сгенерированный класс Python имеет хеш-функцию по умолчанию, где значение хеш-функции связано с расположением объекта в памяти. (В моей 64-битной ОС значение хеша - это место, разделенное на 8.)
Когда я предоставляю класс Python, члены которого могут быть изменены (любая изменяемая структура данных, так что это очень распространенная ситуация!), Я не хочу использовать хэш-функцию по умолчанию, но хочу вызвать hash()
поднять же TypeError
как пользователи получают для Python собственные изменяемые типы данных. В частности, пользователи не должны иметь возможность случайно использовать изменяемые объекты в качестве ключей словаря. Как я могу добиться этого в коде C++?
2 ответа
Я узнал, как это происходит:
boost::python::class_<MyClass>("MyClass")
.setattr("__hash__", boost::python::object());
boost::python::object
который инициализируется без аргументов, соответствует None
, Процедура отключения генерации хеша в чистом API Python C немного сложнее, как описано в документации по Python. Однако приведенный выше фрагмент кода, очевидно, выполняет свою работу в boost::python.
О sidenote: Поведение Boost.Python отражает поведение классов по умолчанию в Python, где объекты в основном можно хэшировать с идентификатором объекта (производным от id(x)):
>>> hash(object())
8795488122377
>>> class MyClass(object): pass
...
>>> hash(MyClass)
878579
>>> hash(MyClass())
8795488082665
>>>