Come tttthomasssss
note, il type
(classe) per np.float64
e d
sono diversi. Essi sono diversi tipi di cose:
In [435]: type(np.float64)
Out[435]: type
Tipo type
mezzi (di solito) che è una funzione, in modo che possa essere utilizzato come:
In [436]: np.float64(0)
Out[436]: 0.0
In [437]: type(_)
Out[437]: numpy.float64
creazione di un oggetto numerico. In realtà sembra più una definizione di classe. Ma dal momento che numpy
utilizza un sacco di codice compilato e il suo ndarray
utilizza il proprio __new__
, non sarei sorpreso se si trova a cavallo della linea.
In [438]: np.float64.__hash__??
Type: wrapper_descriptor
String Form:<slot wrapper '__hash__' of 'float' objects>
Docstring: x.__hash__() <==> hash(x)
pensavo questo sarebbe il hash(np.float64)
, ma potrebbe in realtà essere l'hash per un oggetto di quel tipo, per esempio hash(np.float64(0))
. In tal caso, hash(np.float64)
utilizza solo il metodo predefinito type.__hash__
.
Passando al dtype
:
In [439]: d=np.dtype(np.float64)
In [440]: type(d)
Out[440]: numpy.dtype
d
non è una funzione o di classe:
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)
Sembra np.dtype
non definisce alcun metodo speciale __hash__
, solo eredita da object
.
Inoltre illustra la differenza tra float64
e d
, guarda la pila di ereditarietà di classe
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)
Quindi np.float64
non definisce un hash o, semplicemente eredita da float
. d
non ha un __mro__
perché è un oggetto, non una classe.
numpy
ha abbastanza codice compilato e una lunga storia a parte, che non si può contare sulla documentazione Python sempre valida.
np.dtype
e np.float64
hanno evidentemente __eq__
metodi che consentono loro di essere confrontati tra loro, ma numpy
sviluppatori non ha messo alcun sforzo nel fare in modo che i metodi __hash__
conformi. Molto probabilmente perché non devono essere utilizzati come chiave del dizionario.
codice come non ho mai visto:
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
In realtà 'type (d) == type (np.float64)' è 'False'. E Python dice che solo "I valori numerici che si equivalgono hanno lo stesso valore di hash". – AndyG
Se invece si dice 'd = np.float64', gli hash sono equivalenti. – AndyG
@AndyG Certo, ma è perché sono lo stesso oggetto allora. Python promette che dovrebbero essere uguali se si confrontano uguali. –