为什么numpy.dtype('float64')特别?

Tro*_*lum 8 python numpy

有人可以解释下面脚本输出背后的逻辑吗?

import numpy
if(numpy.dtype(numpy.float64) == None):
    print "Surprise!!!!"
Run Code Online (Sandbox Code Playgroud)

谢谢 :)

Joh*_*nck 8

看起来像一个不幸的事故:有人决定dtype(None)"默认"浮动(虽然dtype()是一个错误).然后有人写了dtype.__eq__这样的话,它在比较之前将它的第二个参数转换为dtype.所以dtype(float) == Nonedtype(float) == dtype(None)这是真的.

你可以在这里看到源代码中的注释:descriptor.c#L1217

  • 从对象获取typenum - 无进入NPY_DEFAULT_TYPE

当然NPY_DEFAULT_TYPE是浮点数(至少通常是).

至于__eq__运算符,它在这里:descriptor.c#L3317.它完成我概述的内容:

if (!PyArray_DescrCheck(other)) {
    if (PyArray_DescrConverter(other, &new) == NPY_FAIL) {
        return NULL;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以这是从右边的任何东西==到dtype对象的转换,通过之前提到的转换器函数转换Nonedtype(float).

编辑:我发现这非常有趣,这似乎是一个意外,所以我创建了一个补丁并提交给维护者:https://github.com/numpy/numpy/pull/4532.


jta*_*lor 4

如果你想在 python 中比较任意对象,None你需要使用:

object is None
Run Code Online (Sandbox Code Playgroud)

就像在这种情况下一样,任何对象都可以覆盖其比较运算符,以不执行您所期望的操作。

至于为什么, dtype('float64') 在 dtypes 的上下文中相当于 None,就像 dtypes 相当于 typestrings 一样

np.dtype('i4') == 'i4'
True
Run Code Online (Sandbox Code Playgroud)

平等不是身份。

至于为什么dtype(None) == dtype('float64'),numpy 中的许多函数都有dtype=None关键字参数。在大多数情况下,这意味着默认数据类型是dtype(None). 一个例子是np.zeros。但也有例外,例如,当可以从参数推断出 dtype 时,就像np.arange(10)默认 dtype 为整数类型的情况(np.intp我认为)。