防止可变类的自动哈希函数

时间:2013-02-25 01:49:18

标签: boost-python

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

hash((1,2,3))

有效,但

hash([1,2,3])

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

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

2 个答案:

答案 0 :(得分:4)

我发现它是怎么回事:

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

使用无参数初始化的boost::python::object对应None。在纯Python C API中禁用哈希生成的过程稍微复杂一些,如Python documentation中所述。但是,上面的代码片段显然是在boost :: python中完成的。

答案 1 :(得分:0)

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

>>> hash(object())
8795488122377
>>> class MyClass(object): pass
... 
>>> hash(MyClass)
878579
>>> hash(MyClass())
8795488082665
>>>