np.sum(a)的结果是NumPy标量,而不是数组.仅涉及标量的操作使用涉及(正维)NumPy数组的操作的不同转换规则,如

numpy.result_type的文档中所述.

当操作仅涉及标量(包括0维数组)时,结果dtype完全由输入dtypes确定.对于仅涉及(正维)数组的操作也是如此.

但是,当标量和(正维)数组混合使用时,NumPy不会使用标量的实际dtypes,而是检查标量的值以查看“较小”的dtype是否可以保存它们,然后将该dtype用于该类型推广. (数组不会经历这个过程,即使它们的值适合较小的dtype.)

从而,

np.sum(a)+1

是一个标量操作,将1转换为dtype int_的NumPy标量(int32或int64,具体取决于C long的大小),然后根据dtypes float32和int32 / int64执行提升,但是

a+1

涉及一个数组,因此为了促销的目的,将1的dtype视为int8.

由于float32无法保存dtype int32(或int64)的所有值,因此NumPy会在第一次促销时升级到float64. (float64不能保存dtype int64的所有值,但NumPy不会为此提升为numpy.longdouble.)由于float32可以保存dtype int8的所有值,因此NumPy会使用float32进行第二次促销.

如果使用大于1的数字,则它不适合int8:

In [16]: (a+1).dtype
Out[16]: dtype('float32')
In [17]: (a+1000000000).dtype
Out[17]: dtype('float64')

你可以看到不同的促销行为.