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

时间:2014-03-22 07:59:29

标签: python numpy

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

import numpy
if(numpy.dtype(numpy.float64) == None):
    print "Surprise!!!!"

谢谢:)

2 个答案:

答案 0 :(得分: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;
    }
}

这是从==右侧的任何内容转换为dtype对象,通过之前提到的转换器函数,将None转换为dtype(float)

编辑:我觉得这很有趣,看起来很意外,所以我创建了一个补丁并提交给维护者:https://github.com/numpy/numpy/pull/4532

答案 1 :(得分:4)

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

object is None

就像在这种情况下一样,任何对象都可以覆盖其比较运算符,而不是按照您的预期行事。

至于为什么,dtype('float64')在dtypes的上下文中等同于None,dtypes等同于typestrings

np.dtype('i4') == 'i4'
True

平等不是身份。

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