有人可以解释以下脚本输出背后的逻辑吗?
import numpy
if(numpy.dtype(numpy.float64) == None):
print "Surprise!!!!"
谢谢:)
答案 0 :(得分:8)
看起来像一个不幸的事故:有人决定dtype(None)
将“默认”浮动(尽管dtype()
是一个错误)。然后有人写了dtype.__eq__
这样它在比较之前将它的第二个参数转换为dtype。所以dtype(float) == None
是dtype(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
)。