什么时候计算python对象的哈希值,为什么-1的哈希值不同?

wim*_*wim 22 python hash

这个问题后,我很想知道什么时候是python对象的哈希计算

  1. 在一个实例的__init__时候,
  2. 第一次__hash__()叫,
  3. 每次都__hash__()被称为,或
  4. 我可能会失踪的任何其他机会?

这可能会根据对象的类型而有所不同吗?

为什么hash(-1) == -2其他整数与哈希相等?

Pet*_*rin 22

哈希值通常在每次使用时计算,因为您可以很容易地检查自己(见下文).当然,任何特定对象都可以自由地缓存其哈希值.例如,CPython字符串执行此操作,但元组不执行此操作(例如,请参阅此拒绝的错误报告).

散列值-1 表示 CPython中的错误.这是因为C没有异常,因此需要使用返回值.当Python对象__hash__返回-1时,CPython实际上会以静默方式将其更改为-2.

你自己看:

class HashTest(object):
    def __hash__(self):
        print('Yes! __hash__ was called!')
        return -1

hash_test = HashTest()

# All of these will print out 'Yes! __hash__ was called!':

print('__hash__ call #1')
hash_test.__hash__()

print('__hash__ call #2')
hash_test.__hash__()

print('hash call #1')
hash(hash_test)

print('hash call #2')
hash(hash_test)

print('Dict creation')
dct = {hash_test: 0}

print('Dict get')
dct[hash_test]

print('Dict set')
dct[hash_test] = 0

print('__hash__ return value:')
print(hash_test.__hash__())  # prints -1
print('Actual hash value:')
print(hash(hash_test))  # prints -2
Run Code Online (Sandbox Code Playgroud)


rpl*_*lnt 6

这里:

哈希值-1是保留的(它用于标记C实现中的错误).如果哈希算法生成此值,我们只需使用-2代替.

由于整数的哈希是整数本身,它只是立即改变.