2

Python 只允许不可变对象的哈希值。例如,

hash((1,2,3))

有效,但是

hash([1,2,3])

提出一个TypeError: unhashable type: 'list'。请参阅Python 文档。但是,当我通过常用函数在 Boost.Python 中包装 C++ 类时boost::python::class_<>,每个生成的 Python 类都有一个默认哈希函数,其中哈希值与对象在内存中的位置有关。(在我的 64 位操作系统上,哈希值是位置除以 8。)

当我向 Python 公开一个可以更改其成员的类时(任何可变数据结构,所以这是一种非常常见的情况!),我不想要一个默认的哈希函数,但想要一个调用来hash()引发与TypeError用户收到的 Python 自己的相同的调用可变数据类型。特别是,用户不应该意外地将可变对象用作字典键。如何在 C++ 代码中实现这一点?

4

2 回答 2

4

我发现它是怎么回事:

boost::python::class_<MyClass>("MyClass")
  .setattr("__hash__", boost::python::object());

没有参数初始化的Aboost::python::object对应于None。在纯 Python C API 中禁用哈希生成的过程稍微复杂一些,如Python 文档中所述。然而,上面的代码片段显然在 boost::python 中完成了这项工作。

于 2013-03-02T23:11:43.820 回答
0

旁注:Boost.Python 的行为反映了 Python 中类的默认行为,其中对象基本上是可散列的,因为对象 id(派生自 id(x)):

>>> hash(object())
8795488122377
>>> class MyClass(object): pass
... 
>>> hash(MyClass)
878579
>>> hash(MyClass())
8795488082665
>>> 
于 2015-04-20T13:35:49.187 回答