开发者

How is hash(None) calculated?

开发者 https://www.devze.com 2023-04-11 02:43 出处:网络
On my machine, hash(None) returns a value: >>> hash(None) -2138947203 Just out of curiosity, h开发者_C百科ow is this hash value calculated?It doesn\'t seem as though this value is based on

On my machine, hash(None) returns a value:

>>> hash(None)
-2138947203

Just out of curiosity, h开发者_C百科ow is this hash value calculated? It doesn't seem as though this value is based on None's id as it is the same if I restart the Python interpreter.


It is based on None's id, but None is one of a few Python objects that are defined as C global variables, so its address (typically) doesn't change between Python runs. Other such objects are True and False (but these are hashed as ints), or built-in classes like object and tuple.

The address (and hash) is different between different CPython builds, however. On my system, hash(None) gives 539708.


It's based on the address of None in memory, as the type definition says.


As None is an object, I've wrote a function object_hash for calculation of object hash:

import sys
import struct

def int_overflow(value):
    """ simulate integer overflow """
    m = sys.maxint + 1
    return (value + m) % (m * 2) - m

def object_hash(value):
    res = id(value)
    sizeof_void_p = struct.calcsize('P')
    res = int_overflow((res >> 4) | (res << (8 * sizeof_void_p - 4)))
    if res == -1:
        res = -2
    return res

The resulting hashes are equal:

>>> hash(None)
492116
>>> object_hash(None)
492116L


Since Python v3.12.0a4 and CPython PR #99541, the hash value of None is now contant.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号