本文介绍了Python 3.2中如何实现__hash__?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我想使自定义对象可以哈希(通过酸洗)。我可以为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 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 对于字符串,您可以看看 http://svn.python.org/view/python/trunk/Objects/stringobject.c?view=markup 第1263行string_hash(PyStringObject * a) I want to make custom object hash-able (via pickling). I could find __hash__ algorithm for Python 2.x (see code below), but it obviously differs from hash for Python 3.2 (I wonder why?). Does anybody know how __hash__ implemented in Python 3.2?#Version: Python 3.2def c_mul(a, b): #C type multiplication return eval(hex((int(a) * b) & 0xFFFFFFFF)[:-1])class hs: #Python 2.x algorithm for hash from http://effbot.org/zone/python-hash.htm def __hash__(self): if not self: return 0 # empty value = ord(self[0]) << 7 for char in self: value = c_mul(1000003, value) ^ ord(char) value = value ^ len(self) if value == -1: value = -2 return valuedef main(): s = ["PROBLEM", "PROBLEN", "PROBLEO", "PROBLEP"]#, "PROBLEQ", "PROBLER", "PROBLES"] print("Python 3.2 hash() bild-in") for c in s[:]: print("hash('", c, "')=", hex(hash(c)), end="\n") print("\n") print("Python 2.x type hash: __hash__()") for c in s[:]: print("hs.__hash__('", c, "')=", hex(hs.__hash__(c)), end="\n")if __name__ == "__main__": main()OUTPUT:Python 3.2 hash() bild-inhash(' PROBLEM ')= 0x7a8e675ahash(' PROBLEN ')= 0x7a8e6759hash(' PROBLEO ')= 0x7a8e6758hash(' PROBLEP ')= 0x7a8e6747Python 2.x type hash: __hash__()hs.__hash__(' PROBLEM ')= 0xa638a41hs.__hash__(' PROBLEN ')= 0xa638a42hs.__hash__(' PROBLEO ')= 0xa638a43hs.__hash__(' PROBLEP ')= 0xa638a5cEdit: 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=markupstatic long1263 string_hash(PyStringObject *a)1264 {1265 register Py_ssize_t len;1266 register unsigned char *p;1267 register long x;12681269 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_infoFor 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__?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-18 14:13