2013-02-25 25 views
2

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++代碼中實現這一點?

回答

4

我發現它是如何去:

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

一個boost::python::object這是不帶參數初始化對應於None。在純Python C API中禁用哈希生成的過程稍微複雜一些,如Python documentation中所述。然而,上面的代碼片段顯然是在boost :: python中完成的。

0

在一個旁註:所述的Boost.Python行爲反映的在Python,其中對象是作爲對象ID的哈希的基本類的默認​​行爲(從ID衍生(X)):

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