Python 3.2中如何实现__hash__? [英] How __hash__ is implemented in Python 3.2?
问题描述
我想使自定义对象可以哈希(通过酸洗)。我可以为Python 2.x找到 __ hash __
算法(参见下面的代码),但它显然与Python 3.2的hash不同(我想知道为什么? )。有人知道如何在Python 3.2中实现 __ hash __
吗?
#Version: Python 3.2
def c_mul(a,b):
#C类型乘法
return eval(十六进制((int(a)* b)& 0xFFFFFFFF)[: 1])$ b
$ b class hs:
#Python 2.x散列算法http://effbot.org/zone/python-hash.htm
def __hash __(self ):
如果不是self:
return 0#empty
value = ord(self [0])<<
value = c_mul(1000003,value)^ ord(char)
value = value ^ len(self)
if value == -1:
value = -2
返回值
$ b def main():
s = [PROBLEM,PROBLEN,PROBLEO, PROBLEP]#,PROBLEQ,PROBLER,PROBLES]
print(Python 3.2 hash()bild-in)
for s [:]:print(hash ('',c,'')=,hex(hash(c)),end =\\\
)
print(\\\
)
print(Python 2。对于c中的s [:]:print(hs .__ hash __(',c,')=,hex(hs .__ hash __(c)),end =\\\
)
if __name__ ==__main__:
main()
OUTPUT:
Python 3.2 hash()bild-in
hash('PROBLEM')= 0x7a8e675a
hash('PROBLEN')= 0x7a8e6759
hash('PROBLEO')= 0x7a8e6758 $ b $ hash('PROBLEP')= 0x7a8e6747
Python 2.x类型的哈希:__hash__ ()
hs .__ hash __('PROBLEM')= 0xa638a41
hs .__ hash __('PROBLEN')= 0xa638a42
hs .__ hash __('PROBLEO')= 0xa638a43
hs。 __hash __('PROBLEP')= 0xa638a5c
编辑: Python 3.2哈希值现在是新类型的值,Py_hash_t等。
Edit2 @Pih谢谢[link] http://svn.python.org/view/python/trunk /Objects/stringobject.c?view=markup
static long
1263 string_hash(PyStringObject * a )
1264 {
1265寄存器Py_ssize_t len;
1266寄存器无符号字符* p;
1267寄存器长x;
1268
1269 if(a-> ob_shash!= -1)
1270 return a-> ob_shash;
1271 len = Py_SIZE(a);
1272 p =(unsigned char *)a-> ob_sval;
1273 x = * p < 7; (--len> = 0)
1275 x =(1000003 * x)^ * p ++;
1276 x ^ = Py_SIZE(a);
1277 if(x == -1)
1278 x = -2;
1279 a-> ob_shash = x;
1280 return x;
1281}
不同的是写在那里:
哈希值现在是一个新的
类型的值,Py_hash_t被定义为
与指针大小相同。
之前它们的类型是long,
,在一些64位操作系统上
仍然只有32位长。
哈希也考虑计算新值,看一看
sys.hash_info
OUTPUT:
Python 3.2 hash() bild-in
hash(' PROBLEM ')= 0x7a8e675a
hash(' PROBLEN ')= 0x7a8e6759
hash(' PROBLEO ')= 0x7a8e6758
hash(' PROBLEP ')= 0x7a8e6747
Python 2.x type hash: __hash__()
hs.__hash__(' PROBLEM ')= 0xa638a41
hs.__hash__(' PROBLEN ')= 0xa638a42
hs.__hash__(' PROBLEO ')= 0xa638a43
hs.__hash__(' PROBLEP ')= 0xa638a5c
Edit: Difference explained, for Python 3.2 "Hash values are now values of a new type, Py_hash_t,etc.."
Edit2 @Pih Thanks [link] http://svn.python.org/view/python/trunk/Objects/stringobject.c?view=markup
static long
1263 string_hash(PyStringObject *a)
1264 {
1265 register Py_ssize_t len;
1266 register unsigned char *p;
1267 register long x;
1268
1269 if (a->ob_shash != -1)
1270 return a->ob_shash;
1271 len = Py_SIZE(a);
1272 p = (unsigned char *) a->ob_sval;
1273 x = *p << 7;
1274 while (--len >= 0)
1275 x = (1000003*x) ^ *p++;
1276 x ^= Py_SIZE(a);
1277 if (x == -1)
1278 x = -2;
1279 a->ob_shash = x;
1280 return x;
1281 }
The answer why they are different is written there:
Hash values are now values of a new type, Py_hash_t, which is defined to be the same size as a pointer. Previously they were of type long, which on some 64-bit operating systems is still only 32 bits long.
The hashing also consider new values to be calculate, take a look at
sys.hash_info
For strings, you can take a look at http://svn.python.org/view/python/trunk/Objects/stringobject.c?view=markup line 1263 string_hash(PyStringObject *a)
这篇关于Python 3.2中如何实现__hash__?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!