gpt4 book ai didi

python - 为什么这些 dtypes 比较相等但散列不同?

转载 作者:行者123 更新时间:2023-12-03 20:48:55 25 4
gpt4 key购买 nike

In [30]: import numpy as np

In [31]: d = np.dtype(np.float64)

In [32]: d
Out[32]: dtype('float64')

In [33]: d == np.float64
Out[33]: True

In [34]: hash(np.float64)
Out[34]: -9223372036575774449

In [35]: hash(d)
Out[35]: 880835502155208439

为什么这些 dtypes 比较相等但散列不同?

请注意,Python 确实 promise :

The only required property is that objects which compare equal have the same hash value…



我解决此问题的方法是调用 np.dtype在所有内容上,之后哈希值和比较都是一致的。

最佳答案

正如 tttthomasssss 所指出的,typenp.float64d(类)是不同的。它们是不同种类的东西:

In [435]: type(np.float64)
Out[435]: type

类型 type 意味着(通常)它是一个函数,因此它可以用作:
In [436]: np.float64(0)
Out[436]: 0.0

In [437]: type(_)
Out[437]: numpy.float64

创建一个数字对象。实际上,这看起来更像是一个类定义。但是由于 numpy 使用了大量的编译代码,并且它的 ndarray 使用它自己的 __new__ ,所以如果它跨越这条线,我不会感到惊讶。
In [438]: np.float64.__hash__??
Type: wrapper_descriptor
String Form:<slot wrapper '__hash__' of 'float' objects>
Docstring: x.__hash__() <==> hash(x)

我在想这将是 hash(np.float64) ,但它实际上可能是该类型对象的哈希,例如 hash(np.float64(0)) 。在这种情况下, hash(np.float64) 只使用默认的 type.__hash__ 方法。

继续 dtype :
In [439]: d=np.dtype(np.float64)

In [440]: type(d)
Out[440]: numpy.dtype
d 不是函数或类:
In [441]: d(0)
...
TypeError: 'numpy.dtype' object is not callable

In [442]: d.__hash__??
Type: method-wrapper
String Form:<method-wrapper '__hash__' of numpy.dtype object at 0xb60f8a60>
Docstring: x.__hash__() <==> hash(x)

看起来 np.dtype 没有定义任何特殊的 __hash__ 方法,它只是继承自 object

进一步说明 float64d 的区别,看类继承栈
In [443]: np.float64.__mro__
Out[443]:
(numpy.float64,
numpy.floating,
numpy.inexact,
numpy.number,
numpy.generic,
float,
object)

In [444]: d.__mro__
...
AttributeError: 'numpy.dtype' object has no attribute '__mro__'

In [445]: np.dtype.__mro__
Out[445]: (numpy.dtype, object)

所以 np.float64 也没有定义散列,它只是继承自 floatd 没有 __mro__ 因为它是一个对象,而不是一个类。
numpy 有足够多的编译代码,以及它自己的悠久历史,你不能指望 Python 文档总是适用。
np.dtypenp.float64 显然有 __eq__ 方法可以让它们相互比较,但是 numpy 开发人员并没有付出任何努力来确保 __hash__ 方法符合。很可能是因为他们不需要将任何一个用作字典键。

我从未见过这样的代码:
In [453]: dd={np.float64:12,d:34}

In [454]: dd
Out[454]: {dtype('float64'): 34, numpy.float64: 12}

In [455]: dd[np.float64]
Out[455]: 12

In [456]: dd[d]
Out[456]: 34

关于python - 为什么这些 dtypes 比较相等但散列不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64071440/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com