Python的hash()无法处理长整型?

9 投票
3 回答
3735 浏览
提问于 2025-04-15 21:53

我定义了一个类:

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

为什么在测试中,hash()函数会返回一个负整数呢?

3 个回答

4

哈希函数的目的是把一组输入分散到一系列的键上,所以这些键不一定非得是正整数。

在Python中,哈希函数返回负整数只是实现上的一个细节,而且只限于长整型。例如,在我的系统上,hash('abc')的结果是负数。

7

请查看 object.__hash__

注意到以下内容:

在2.5版本中进行了更改:__hash__() 现在也可以返回一个长整型对象;然后32位整数是从该对象的哈希值中得出的。

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

Python通过 (12544897317 & 0xFFFFFFFF) - (1<<32) 得出了32位整数 -340004569

Python通过 hash(12544897317L) 得出了32位整数 -340004569

这个算法大致是这样的:

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
10

看起来这个限制在32位系统上。根据这个问题,你的代码在64位机器上可能得到了预期的结果(因为那些特定的值可以在64位中表示)。

内置的hash函数的结果是依赖于平台的,并且受到本地字长的限制。如果你需要一个稳定的、跨平台的哈希值,可以考虑使用hashlib模块。

撰写回答