python hash()无法处理长整数?

Python hash() can't handle long integer?

我定义了一个类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A:
    ''' hash test class
    >>> a = A(9, 1196833379, 1, 1773396906)
    >>> hash(a)
    -340004569

    This is weird, 12544897317L expected.
    '''

    def __init__(self, a, b, c, d):
        self.a = a
        self.b = b
        self.c = c
        self.d = d

    def __hash__(self):
        return self.a * self.b + self.c * self.d

为什么在doctest中,hash()函数给出一个负整数?


它似乎仅限于32位。通过阅读这个问题,您的代码可能已经在64位机器上产生了预期的结果(使用这些特定的值,因为结果适合64位)。

内置的hash函数的结果依赖于平台,并限制为本机单词大小。如果需要确定的跨平台哈希,请考虑使用hashlib模块。


object.__hash__

注意到

Changed in version 2.5: __hash__() may
now also return a long integer object;
the 32-bit integer is then derived
from the hash of that object.

在您的例子中,预期的12544897317L是一个长整型对象,

python derived the 32-bit integer-340004569 by (12544897317 & 0xFFFFFFFF) - (1<<32)del>

python通过散列(12544897317L)派生了32位整数,结果是-340004569

算法是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
def s32(x):
    x = x & ((1<<32)-1)
    if x & (1<<31):
        return x - (1<<32)
    else:
        return x

def hash(x):
    h = 0
    while x:
        h += s32(x)
        x >>= 32
    return h


因为散列函数的目的是获取一组输入并将它们分布在一系列键上,所以这些键不必是正整数。

pythons散列函数返回负整数这一事实只是一个实现细节,并且必须限于长整数。例如,哈希("abc")在我的系统中是负数。