NumPy 2.0.0 版本说明#
注意
2.0 版本正在发布,当前的版本概述和亮点仍处于草稿阶段。但是,亮点应该已经列出了下面完整说明中详细介绍的最重大变化,并且这些完整说明应该已经完成(即使还没有经过充分的校对)。
NumPy 2.0.0 是自 2006 年以来的第一个主要版本。它是自上一个功能版本发布以来 11 个月的开发结果,是 212 位贡献者在 1078 个拉取请求中共同努力的结果。它包含大量激动人心的新功能,以及对 Python 和 C API 的更改。
这个主要版本包括无法在常规次要(功能)版本中实现的重大变更 - 包括 ABI 中断、类型提升规则的更改,以及在 1.26.x 中可能未发出弃用警告的 API 更改。除了这些版本说明之外,与如何适应 NumPy 2.0 中更改相关的关键文档包括
The NumPy 2.0 迁移指南
The NumPy 2.0 特定的建议 in 针对下游包作者
亮点#
本版本的主要亮点包括
新功能
一种新的可变长度字符串数据类型,
StringDType
,以及一个新的numpy.strings
命名空间,其中包含用于字符串操作的高效通用函数。在所有
numpy.fft
函数中支持float32
和longdouble
。在主
numpy
命名空间中支持数组 API 标准。
性能改进
排序函数(
sort
,argsort
,partition
,argpartition
)通过使用 Intel x86-simd-sort 和 Google Highway 库得到了加速,并且可能会看到很大的(硬件特定)加速。macOS Accelerate 支持和针对 macOS >=14 的二进制轮子,针对 macOS 上的线性代数操作提供了显著的性能改进,并且轮子的大小缩小了约 3 倍。
numpy.char
固定长度字符串操作通过实现也支持StringDType
的通用函数而得到了加速,除了固定长度字符串数据类型之外。一个新的跟踪和内省 API,
opt_func_info
,用于确定哪些硬件特定内核可用,并将调度到哪些内核。numpy.save
现在使用 pickle 协议版本 4 来保存具有对象数据类型的数组,这允许 pickle 对象大于 4GB,并且对于大型数组,保存速度提高了约 5%。
Python API 改进
C API 改进
一个新的 用于创建自定义数据类型的公共 C API。
删除了许多过时的函数和宏,并将私有内部内容隐藏起来,以简化未来的扩展。
新的、更易于使用的初始化函数:
PyArray_ImportNumPyAPI
和PyUFunc_ImportUFuncAPI
。
改进的行为
通过采用 NEP 50,类型提升行为得到了改进。这修复了许多用户对提升的意外行为,这些意外行为以前通常取决于输入数组的数据值,而不是仅取决于其数据类型。有关详细信息,请参阅 NEP 和 NumPy 2.0 迁移指南,因为此更改可能会导致输出数据类型的变化,以及混合数据类型操作的精度降低。
Windows 上的默认整数类型现在是
int64
而不是int32
,与其他平台上的行为一致。数组维度的最大数量已从 32 更改为 64。
文档
此外,NumPy 内部还有许多变化,包括继续将代码从 C 迁移到 C++,这将使将来更容易改进和维护 NumPy。
“没有免费午餐”定理表明,所有这些 API 和行为改进以及更好的未来可扩展性都需要付出代价。这个代价是
向后兼容性。对 Python 和 C API 都有大量的重大变更。在大多数情况下,会有明确的错误消息告知用户如何调整他们的代码。但是,也有一些行为变化,无法给出这样的错误消息 - 这些情况都在下面的弃用和兼容性部分以及 NumPy 2.0 迁移指南 中介绍。
请注意,有一个
ruff
模式可以自动修复 Python 代码中的许多问题。对 NumPy ABI 的重大变更。因此,使用 NumPy C API 并针对 NumPy 1.xx 版本构建的包的二进制文件将无法与 NumPy 2.0 一起使用。在导入时,这些包将看到一个
ImportError
,其中包含有关二进制不兼容性的消息。可以针对 NumPy 2.0 构建在运行时既能与 NumPy 2.0 又能与 1.x 一起使用的二进制文件。有关更多详细信息,请参阅 NumPy 2.0 特定的建议。
建议所有依赖 NumPy ABI 的下游包进行新的针对 NumPy 2.0 构建的版本发布,并验证该版本既能与 2.0 又能与 1.26 一起使用 - 理想情况下,在 2.0.0rc1(将是 ABI 稳定的)和最终的 2.0.0 版本发布之间的时间段内进行,以避免为其用户造成问题。
本版本支持的 Python 版本为 3.9-3.12。
NumPy 2.0 Python API 删除#
np.geterrobj
,np.seterrobj
以及相关的通用函数关键字参数extobj=
已被删除。所有这些的推荐替代方法是使用上下文管理器with np.errstate():
。(gh-23922)
np.cast
已被删除。np.cast[dtype](arg)
的文字替代方法是np.asarray(arg, dtype=dtype)
。np.source
已被删除。推荐替代方法是inspect.getsource
。np.lookfor
已被删除。(gh-24144)
numpy.who
已被删除。作为已删除功能的替代方案,可以使用 Spyder 或 Jupyter Notebook 等 IDE 中提供的变量资源管理器。(gh-24321)
在
numpy.exceptions
中存在的警告和异常(例如,ComplexWarning
,VisibleDeprecationWarning
)不再在主命名空间中公开。多个利基枚举、已过期的成员和函数已从主命名空间中删除,例如:
ERR_*
,SHIFT_*
,np.fastCopyAndTranspose
,np.kernel_version
,np.numarray
,np.oldnumeric
和np.set_numeric_ops
。(gh-24316)
在
numpy/__init__.py
中将from ... import *
替换为显式导入。因此,这些主命名空间成员被删除:np.FLOATING_POINT_SUPPORT
,np.FPE_*
,np.NINF
,np.PINF
,np.NZERO
,np.PZERO
,np.CLIP
,np.WRAP
,np.WRAP
,np.RAISE
,np.BUFSIZE
,np.UFUNC_BUFSIZE_DEFAULT
,np.UFUNC_PYVALS_NAME
,np.ALLOW_THREADS
,np.MAXDIMS
,np.MAY_SHARE_EXACT
,np.MAY_SHARE_BOUNDS
,add_newdoc
,np.add_docstring
和np.add_newdoc_ufunc
。(gh-24357)
别名
np.float_
已被删除。请使用np.float64
代替。别名
np.complex_
已被删除。请使用np.complex128
代替。别名
np.longfloat
已被删除。请使用np.longdouble
代替。别名
np.singlecomplex
已被删除。请使用np.complex64
代替。别名
np.cfloat
已被删除。请使用np.complex128
代替。别名
np.longcomplex
已被删除。请使用np.clongdouble
代替。别名
np.clongfloat
已被删除。请使用np.clongdouble
代替。别名
np.string_
已被删除。请使用np.bytes_
代替。别名
np.unicode_
已被删除。请使用np.str_
代替。别名
np.Inf
已被删除。请使用np.inf
代替。别名
np.Infinity
已被删除。请使用np.inf
代替。别名
np.NaN
已被删除。请使用np.nan
代替。别名
np.infty
已被删除。请使用np.inf
代替。别名
np.mat
已被移除。请使用np.asmatrix
代替。np.issubclass_
已被移除。请使用内建函数issubclass
代替。np.asfarray
已被移除。请使用np.asarray
并指定合适的 dtype 代替。np.set_string_function
已被移除。请使用np.set_printoptions
并指定一个格式化程序来自定义 NumPy 对象的打印方式。np.tracemalloc_domain
现在只能从np.lib
中访问。np.recfromcsv
和np.recfromtxt
已从主命名空间中移除。请使用np.genfromtxt
并指定逗号作为分隔符代替。np.issctype
、np.maximum_sctype
、np.obj2sctype
、np.sctype2char
、np.sctypes
、np.issubsctype
都已从主命名空间中移除,没有替代方案,因为它们是比较小众的成员。已弃用的
np.deprecate
和np.deprecate_with_doc
已从主命名空间中移除。请使用DeprecationWarning
代替。已弃用的
np.safe_eval
已从主命名空间中移除。请使用ast.literal_eval
代替。(gh-24376)
np.find_common_type
已被移除。请使用numpy.promote_types
或numpy.result_type
代替。为了实现scalar_types
参数的语义,请使用numpy.result_type
并传递0
、0.0
或0j
作为 Python 标量代替。np.round_
已被移除。请使用np.round
代替。np.nbytes
已被移除。请使用np.dtype(<dtype>).itemsize
代替。(gh-24477)
np.compare_chararrays
已从主命名空间中移除。请使用np.char.compare_chararrays
代替。主命名空间中的
charrarray
已被弃用。目前,它可以从np.char.chararray
中导入,不会触发弃用警告,但我们计划在未来完全弃用并移除chararray
。np.format_parser
已从主命名空间中移除。请使用np.rec.format_parser
代替。(gh-24587)
对
np.dtype
中七个数据类型字符串别名的支持已被移除:int0
、uint0
、void0
、object0
、str0
、bytes0
和bool8
。(gh-24807)
实验性的
numpy.array_api
子模块已被移除。请使用主numpy
命名空间进行常规使用,或使用单独的array-api-strict
包进行合规性测试用例,因为numpy.array_api
主要用于此用例。(gh-25911)
__array_prepare__
已被移除#
在运行常规 ufunc 调用(不包括广义 ufunc、约简等)的计算之前,UFuncs 会调用 __array_prepare__
。该函数也会在某些线性代数函数的结果上调用,而不是调用 __array_wrap__
。
它现在已被移除。如果您使用了它,请迁移到 __array_ufunc__
或依赖于 __array_wrap__
,它在所有情况下都会被调用,尽管只有在结果数组填充后才会调用。在这些代码路径中,__array_wrap__
现在将被传递一个基类,而不是一个子类数组。
(gh-25105)
弃用#
np.compat
已被弃用,因为不再支持 Python 2。numpy.int8
和类似的类将不再支持将超出范围的 Python 整数转换为整数数组。例如,将 255 转换为 int8 不会返回 -1。numpy.iinfo(dtype)
可用于检查数据类型的机器限制。例如,np.iinfo(np.uint16)
返回 min = 0 和 max = 65535。np.array(value).astype(dtype)
将给出所需的结果。np.safe_eval
已被弃用。应改用ast.literal_eval
。(gh-23830)
np.recfromcsv
、np.recfromtxt
、np.disp
、np.get_array_wrap
、np.maximum_sctype
、np.deprecate
和np.deprecate_with_doc
已被弃用。(gh-24154)
np.trapz
已被弃用。请改用np.trapezoid
或scipy.integrate
函数。np.in1d
已被弃用。请改用np.isin
。别名
np.row_stack
已被弃用。请直接使用np.vstack
。(gh-24445)
__array_wrap__
现在被传递arr, context, return_scalar
,对不接受所有三个参数的实现的支持已被弃用。它的签名应该是__array_wrap__(self, arr, context=None, return_scalar=False)
(gh-25409)
针对
np.cross
的二维向量数组已被弃用。请改用三维向量数组。(gh-24818)
np.dtype("a")
是np.dtype(np.bytes_)
的别名,已被弃用。请改用np.dtype("S")
别名。(gh-24854)
使用关键字参数
x
和y
与函数assert_array_equal
和assert_array_almost_equal
一起使用已被弃用。请将前两个参数作为位置参数传递。(gh-24978)
numpy.fft
中对参数中包含 None 值的 n 维变换的弃用#
使用 fftn
、ifftn
、rfftn
、irfftn
、fft2
、ifft2
、rfft2
或 irfft2
,并将 s
参数设置为一个非 None
值,而 axes
参数设置为 None
,已被弃用,与数组 API 标准保持一致。为了保留当前行为,请针对一个维度为 k 的数组,将一个序列 [0, …, k-1] 传递给 axes
。
此外,将一个包含 None
值的数组传递给 s
已被弃用,因为该参数在 NumPy 文档和数组 API 规范中都被记录为接受一个整数序列。为了使用相应一维变换的默认行为,请传递与它的 n
参数的默认值相匹配的值。为了对每个轴使用默认行为,可以省略 s
参数。
(gh-25495)
np.linalg.lstsq
现在默认使用一个新的 rcond
值#
lstsq
现在使用新的 rcond 值,即机器精度乘以 max(M, N)
。之前,使用的是机器精度,但会发出 FutureWarning 以通知最终会发生此更改。通过传递 rcond=-1
仍然可以实现旧的行为。
(gh-25721)
已过期弃用#
np.core.umath_tests
子模块已从公共 API 中移除。(在 NumPy 1.15 中弃用)(gh-23809)
PyDataMem_SetEventHook
的弃用已过期,它已被移除。请使用tracemalloc
和np.lib.tracemalloc_domain
域。(在 NumPy 1.23 中弃用)(gh-23921)
set_numeric_ops
和 C 函数PyArray_SetNumericOps
和PyArray_GetNumericOps
的弃用已过期,这些函数已被移除。(在 NumPy 1.16 中弃用)(gh-23998)
fasttake
、fastclip
和fastputmask
ArrFuncs
的弃用现已完成。已弃用的函数
fastCopyAndTranspose
及其 C 对应项现已移除。PyArray_ScalarFromObject
的弃用现已完成。(gh-24312)
np.msort
已被移除。作为替代方案,请改用np.sort(a, axis=0)
。(gh-24494)
np.dtype(("f8", 1)
现在将返回一个形状为 1 的子数组 dtype,而不是非子数组 dtype。(gh-25761)
对 ndarray 的
.data
属性进行赋值将被禁止,并会引发异常。np.binary_repr(a, width)
如果 width 太小,将引发异常。在
PyArray_DescrFromType()
中使用NPY_CHAR
将引发异常,请改用NPY_STRING
NPY_UNICODE
或NPY_VSTRING
。(gh-25794)
兼容性说明#
loadtxt
和 genfromtxt
的默认编码已更改#
loadtxt
和 genfromtxt
现在都默认使用 encoding=None
,这可能会主要修改 converters
的工作方式。现在将传递 str
而不是 bytes
给它们。显式传递编码以始终获得新旧行为。对于 genfromtxt
,此更改还意味着返回的值现在将是 unicode 字符串而不是字节。
(gh-25158)
f2py
兼容性说明#
f2py
将不再接受模棱两可的-m
和.pyf
CLI 组合。当传递多个.pyf
文件时,会引发错误。当同时传递-m
和.pyf
时,会发出警告,并忽略提供的-m
名称。(gh-25181)
f2py.compile()
帮助程序已被删除,因为它存在内存泄漏问题,并且已经被标记为实验性多年,并且被实现为一个简单的subprocess.run
包装器。它也是测试瓶颈之一。有关完整原因,请参见 gh-25122。它还使用了一些np.distutils
功能,这些功能太脆弱,无法移植到meson
中。强烈建议用户将对
f2py.compile
的调用替换为对subprocess.run("python", "-m", "numpy.f2py",...
的调用,并使用环境变量与meson
交互。 本地文件 也是一种选择。(gh-25193)
排序函数行为的细微变化#
由于算法更改和 SIMD 代码的使用,在 2.0.0 中,与 1.26.x 相比,使用非稳定方法的排序函数可能会返回略微不同的结果。这包括 argsort
和 argpartition
的默认方法。
在 np.solve
中广播时的消除歧义#
当 b
的维度比 a
少一个时,np.solve(a, b)
的广播规则是模棱两可的。这已通过向后不兼容的方式解决,现在符合 Array API。可以通过使用 np.solve(a, b[..., None])[..., 0]
来重建旧的行为。
(gh-25914)
修改了 Polynomial
的表示#
Polynomial
的表示方法已更新,以在表示中包含域。纯文本和 latex 表示现在是一致的。例如,str(np.polynomial.Polynomial([1, 1], domain=[.1, .2]))
的输出曾经是 1.0 + 1.0 x
,但现在是 1.0 + 1.0 (-3.0000000000000004 + 20.0 x)
。
(gh-21760)
C API 更改#
PyArray_CGT
、PyArray_CLT
、PyArray_CGE
、PyArray_CLE
、PyArray_CEQ
、PyArray_CNE
宏已被删除。PyArray_MIN
和PyArray_MAX
已从ndarraytypes.h
移动到npy_math.h
。(gh-24258)
为使用
numpy.dtypes.StringDType
数组的 C API 已公开。这包括用于获取和释放锁定对字符串数据访问的互斥锁的函数,以及将 UTF-8 字节流从数组条目打包和解包。NPY_NTYPES
已重命名为NPY_NTYPES_LEGACY
,因为它不包含新的 NumPy 内置 DType。特别是新的字符串 DType 可能会与处理传统 DType 的代码不兼容。(gh-25347)
C-API 现在只导出数组访问器的静态内联函数版本(以前这取决于使用“已弃用的 API”)。虽然我们不鼓励这样做,但仍然可以直接使用结构体字段。
(gh-25789)
NumPy 现在定义了
PyArray_Pack
来设置单个内存地址。与PyArray_SETITEM
不同,此函数等效于设置单个数组项,不需要 NumPy 数组输入。(gh-25954)
->f
槽已从PyArray_Descr
中删除。如果使用此槽,请使用PyDataType_GetArrFuncs
替换对它的访问(请参见其文档和 NumPy 2.0 迁移指南)。在某些情况下,使用PyArray_GETITEM
等其他函数可能是替代方案。PyArray_GETITEM
和PyArray_SETITEM
现在需要导入 NumPy API 表才能使用,不再定义在ndarraytypes.h
中。(gh-25812)
由于运行时依赖关系,访问 dtype 标志的功能定义已从
numpy/ndarraytypes.h
中移动,并且仅在包含numpy/ndarrayobject.h
后可用,因为它需要import_array()
。这包括PyDataType_FLAGCHK
、PyDataType_REFCHK
和NPY_BEGIN_THREADS_DESCR
。现在必须通过
PyDataType_FLAGS
内联函数访问PyArray_Descr
上的 dtype 标志,才能与 1.x 和 2.x 兼容。此函数定义在npy_2_compat.h
中,以便可以进行回移植。大多数或所有用户都应该使用PyDataType_FLAGCHK
,它在 1.x 上可用,并且不需要回移植。Cython 用户应该使用 Cython 3。否则,除非使用PyDataType_FLAGCHK
,否则访问将通过 Python 进行。(gh-25816)
在 C API 和 Cython 绑定中公开的日期时间功能#
函数 NpyDatetime_ConvertDatetime64ToDatetimeStruct
、NpyDatetime_ConvertDatetimeStructToDatetime64
、NpyDatetime_ConvertPyDateTimeToDatetimeStruct
、NpyDatetime_GetDatetimeISO8601StrLen
、NpyDatetime_MakeISO8601Datetime
和 NpyDatetime_ParseISO8601Datetime
已添加到 C API 中,以方便在外部库中在字符串、Python 日期时间和 NumPy 日期时间之间进行转换。
(gh-21199)
广义 ufunc C API 的常量正确性#
NumPy C API 中用于构建广义 ufunc 的函数(PyUFunc_FromFuncAndData
、PyUFunc_FromFuncAndDataAndSignature
、PyUFunc_FromFuncAndDataAndSignatureAndIdentity
)接受 types
和 data
参数,这些参数不会被 NumPy 的内部机制修改。与 name
和 doc
参数一样,第三方 Python 扩展模块很可能会从静态常量提供这些参数。types
和 data
参数现在是常量正确的:它们分别被声明为 const char *types
和 void *const *data
。C 代码不应该受到影响,但 C++ 代码可能会受到影响。
(gh-23847)
更大的 NPY_MAXDIMS
和 NPY_MAXARGS
,引入了 NPY_RAVEL_AXIS
#
NPY_MAXDIMS
现在是 64,你可能需要检查它的使用。这通常用于堆栈分配,在这种情况下,增加应该是安全的。但是,我们鼓励一般情况下消除对 NPY_MAXDIMS
和 NPY_MAXARGS
的任何使用,以最终允许完全消除约束。对于与 Python 中的 take
等函数相同的转换帮助程序和 C-API 函数,NPY_MAXDIMS
被用于表示 axis=None
。这种用法必须替换为 NPY_RAVEL_AXIS
。另请参见 增加的最大维度数。
(gh-25149)
NPY_MAXARGS
不是常量,PyArrayMultiIterObject
大小变化#
由于 NPY_MAXARGS
已增加,它现在是一个运行时常量,而不是编译时常量。我们预计几乎没有用户会注意到这一点。但是,如果用于堆栈分配,现在必须使用 NPY_MAXARGS
作为额外的运行时检查来替换它。
sizeof(PyArrayMultiIterObject)
不再包含对象的完整大小。我们预计没有人会注意到这种变化。这是为了避免与 Cython 相关的问题。
(gh-25271)
自定义传统用户 dtype 的必要更改#
为了改进我们的 DType,不幸的是必须破坏 ABI,这需要对使用 PyArray_RegisterDataType
注册的 dtype 进行一些更改。请参见 PyArray_RegisterDataType
的文档,了解如何调整代码并与 1.x 和 2.x 保持兼容。
(gh-25792)
新的公共 DType API#
NEP 42 DType API 的 C 实现现在是公开的。虽然 DType API 已经在 NumPy 中发布了几个版本,但它只能在设置了特殊环境变量的会话中使用。现在可以使用新的 DType API 和正常的 import_array()
机制导入 numpy C API,在 NumPy 之外编写自定义 DType。
有关 API 的更多详细信息,请参见 自定义数据类型。与任何新功能一样,请报告在实现或使用新的 DType 时遇到的任何错误。很可能需要更新与 dtype 合作的下游 C 代码,使其与新的 DType 正确兼容。
(gh-25754)
新的 C-API 导入函数#
我们现在添加了 PyArray_ImportNumPyAPI
和 PyUFunc_ImportUFuncAPI
作为静态内联函数,用于导入 NumPy C-API 表。新函数有两个比 import_array
和 import_ufunc
更好的优点
它们检查导入是否已执行,如果未执行,则重量很轻,允许谨慎地添加它们(尽管在大多数情况下这并不理想)。
旧机制是宏而不是函数,其中包含
return
语句。
该 PyArray_ImportNumPyAPI()
函数包含在 npy_2_compat.h
中,用于更简单的回溯。
(gh-25866)
通过函数访问结构化 dtype 信息#
dtype 结构的字段 c_metadata
、names
、fields
和 subarray
现在必须通过遵循相同名称的新函数来访问,例如 PyDataType_NAMES
。由于它们并非所有 PyArray_Descr
实例都存在,因此无法直接访问这些字段。 metadata
字段保留,但应优先使用宏版本。
(gh-25802)
描述符 elsize
和 alignment
访问#
除非仅使用 NumPy 2 支持进行编译,否则 elsize
和 alignment
字段现在必须通过 PyDataType_ELSIZE
、PyDataType_SET_ELSIZE
和 PyDataType_ALIGNMENT
来访问。在描述符附加到数组的情况下,建议使用 PyArray_ITEMSIZE
,因为它存在于所有 NumPy 版本中。请参阅 PyArray_Descr 结构已更改 以获取更多信息。
(gh-25943)
NumPy 2.0 C API 删除#
npy_interrupt.h
和相应的宏(如NPY_SIGINT_ON
)已被删除。我们建议定期查询PyErr_CheckSignals()
或PyOS_InterruptOccurred()
(这些目前确实需要持有 GIL)。该
noprefix.h
头文件已被删除。用带前缀的对应项(通常添加NPY_
或npy_
)替换缺失的符号。(gh-23919)
PyUFunc_GetPyVals
、PyUFunc_handlefperr
和PyUFunc_checkfperr
已被删除。如果需要,可以恢复一个新的向后兼容函数来引发浮点错误。删除原因:没有已知的用户,并且这些函数将使with np.errstate()
修复变得更加困难。(gh-23922)
该
numpy/old_defines.h
自 NumPy 1.7 以来已弃用的 API 部分已被删除。这将删除形式为PyArray_CONSTANT
的宏。 replace_old_macros.sed 脚本可能有助于将它们转换为NPY_CONSTANT
版本。(gh-24011)
ufunc 结构的
legacy_inner_loop_selector
成员已删除,以简化对调度系统的改进。没有已知的用户覆盖或直接访问此成员。(gh-24271)
NPY_INTPLTR
已被删除,以避免混淆(请参阅intp
重新定义)。(gh-24888)
高级索引
MapIter
和相关 API 已被删除。它的(真正)公共部分没有经过充分测试,只有一个已知的用户(Theano)。将其设为私有将简化对加速ufunc.at
的改进,使高级索引更容易维护,并且对于将数组的最大维数增加到 64 非常重要。如果您认为此 API 对您很重要,请告诉我们,以便我们可以一起找到解决方案。(gh-25138)
该
NPY_MAX_ELSIZE
宏已被删除,因为它仅反映内置数值类型,并且没有内部用途。(gh-25149)
PyArray_REFCNT
和NPY_REFCOUNT
已被删除。改用Py_REFCNT
。(gh-25156)
PyArrayFlags_Type
和PyArray_NewFlagsObject
以及PyArrayFlagsObject
现在是私有的。没有已知的用例;如果需要,请使用 Python API。PyArray_MoveInto
、PyArray_CastTo
、PyArray_CastAnyTo
已被删除,使用PyArray_CopyInto
,如果绝对需要,则使用PyArray_CopyAnyInto
(后者执行平面复制)。PyArray_FillObjectArray
已被删除,它唯一的真实用途是用于实现np.empty
。创建一个新的空数组,或使用PyArray_FillWithScalar()
(减少现有对象的引用计数)。PyArray_CompareUCS4
和PyArray_CompareString
已被删除。使用标准 C 字符串比较函数。PyArray_ISPYTHON
已被删除,因为它具有误导性,没有已知的用例,并且易于替换。PyArray_FieldNames
已被删除,因为它不清楚它有什么用处。它在某些可能的用例中也具有不正确的语义。PyArray_TypestrConvert
已被删除,因为它似乎是错误的命名,不太可能被任何人使用。如果您知道大小或仅限于少数类型,请直接显式使用它,否则请通过 Python 字符串进行。(gh-25292)
PyDataType_GetDatetimeMetaData
已被删除,它自 NumPy 1.7 以来实际上没有执行任何操作。(gh-25802)
PyArray_GetCastFunc
已被删除。请注意,自定义旧用户 dtype 仍然可以提供 castfunc 作为其实现,但现在已删除对它们的任何访问。这样做是因为 NumPy 多年来从未在内部使用过这些函数。如果您使用简单的数值类型,请直接使用 C 强制转换。如果您需要替代方案,请告诉我们,以便我们可以创建新的 API,例如PyArray_CastBuffer()
,它可以使用旧的或新的强制转换函数,具体取决于 NumPy 版本。(gh-25161)
新功能#
np.add
已扩展到适用于 unicode
和 bytes
dtype。#
(gh-24858)
一个新的 bitwise_count
函数#
此新函数计算数字中 1 位的数量。 bitwise_count
在所有 numpy 整数类型和类似整数的对象上运行。
>>> a = np.array([2**i - 1 for i in range(16)])
>>> np.bitwise_count(a)
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
dtype=uint8)
(gh-19355)
macOS Accelerate 支持,包括 ILP64#
已添加对 macOS 13.3 中更新的 Accelerate BLAS/LAPACK 库的支持,包括 ILP64(64 位整数)支持。这带来了 arm64 支持,以及对常用线性代数运算的性能大幅提升(最高可达 10 倍)。如果在构建时选择 Accelerate,或者如果没有显式选择 BLAS 库,则如果可用,将自动使用 13.3+ 版本。
(gh-24053)
二进制轮子也可用。在 macOS >=14.0 上,从 PyPI 安装 NumPy 的用户将获得针对 Accelerate 而不是 OpenBLAS 构建的轮子。
(gh-25255)
为分位数和百分位数函数使用权重的选项#
现在 quantile
、percentile
、nanquantile
和 nanpercentile
可用 weights
关键字。只有 method="inverted_cdf"
支持权重。
(gh-24254)
改进的 CPU 优化跟踪#
可以使用一种新的跟踪机制,该机制能够跟踪 NumPy 库中每个优化函数(即使用特定于硬件的 SIMD 指令)的已启用目标。通过此增强功能,可以精确地监控为已调度函数启用的 CPU 调度目标。
一个名为 opt_func_info
的新函数已添加到新的命名空间 numpy.lib.introspect
中,提供了这种跟踪功能。此函数允许您根据函数名称和数据类型签名检索有关已启用目标的信息。
(gh-24420)
一个新的 Meson 后端用于 f2py
#
在编译模式下(即 f2py -c
),f2py
现在接受 --backend meson
选项。对于 Python >=3.12,这是默认选项。对于旧版本的 Python,f2py
仍然默认使用 --backend distutils
。
为了在现实用例中支持这一点,在编译模式下,f2py
会多次使用 --dep
标志,这对应于 meson
后端中的 dependency()
调用,并且在 distutils
后端中不执行任何操作。
对于仅将 f2py
用作代码生成器(即不带 -c
)的用户来说,没有任何变化。
(gh-24532)
bind(c)
支持 f2py
#
函数和子例程都可以用 bind(c)
进行注释。 f2py
将处理正确的类型映射,并保留其他 C 接口的唯一标签。
**注意:** bind(c, name = 'routine_name_other_than_fortran_routine')
不会被 f2py
绑定按设计方式处理,因为 bind(c)
带有 name
旨在保证 C 和 Fortran 中的名称相同,而不是 Python 和 Fortran 中的名称相同。
(gh-24555)
一些测试函数的新的 strict
选项#
现在 assert_allclose
、assert_equal
和 assert_array_less
可用 strict
关键字。将 strict=True
设置为将禁用标量的广播行为,并确保输入数组具有相同的数据类型。
添加 np.core.umath.find
和 np.core.umath.rfind
UFuncs#
添加两个find
和rfind
UFuncs,它们在 unicode 或字节字符串上操作,并用于np.char
。它们的操作类似于str.find
和str.rfind
。
(gh-24868)
diagonal
和trace
用于numpy.linalg
#
numpy.linalg.diagonal
和numpy.linalg.trace
已添加,它们是numpy.diagonal
和numpy.trace
的数组 API 标准兼容变体。它们在默认轴选择方面有所不同,该选择定义了二维子数组。
(gh-24887)
新的long
和ulong
数据类型#
numpy.long
和numpy.ulong
已添加为 NumPy 整数,映射到 C 的long
和unsigned long
。在 NumPy 1.24 之前,numpy.long
是 Python 的int
的别名。
(gh-24922)
svdvals
用于numpy.linalg
#
numpy.linalg.svdvals
已添加。它计算矩阵(或矩阵堆栈)的奇异值。执行np.svdvals(x)
与调用np.svd(x, compute_uv=False, hermitian=False)
相同。此函数与数组 API 标准兼容。
(gh-24940)
一个新的isdtype
函数#
numpy.isdtype
已添加,以提供一种规范的方式来对 NumPy 的数据类型进行分类,符合数组 API 标准。
(gh-25054)
一个新的astype
函数#
numpy.astype
已添加,以提供numpy.ndarray.astype
方法的数组 API 标准兼容替代方案。
(gh-25079)
数组 API 兼容函数的别名#
为现有函数添加了 13 个别名,以提高与数组 API 标准的兼容性
三角函数:
acos
、acosh
、asin
、asinh
、atan
、atanh
、atan2
。位运算:
bitwise_left_shift
、bitwise_invert
、bitwise_right_shift
。杂项:
concat
、permute_dims
、pow
。在
numpy.linalg
中:tensordot
、matmul
。
(gh-25086)
新的unique_*
函数#
unique_all
、unique_counts
、unique_inverse
和unique_values
函数已添加。它们提供unique
的功能,但使用不同的标志集。它们与数组 API 标准兼容,并且由于它们返回的数组数量不依赖于输入参数的值,因此更容易针对 JIT 编译。
(gh-25088)
对 ndarray 的矩阵转置支持#
NumPy 现在提供对计算数组(或数组堆栈)的矩阵转置的支持。矩阵转置等效于交换数组的最后两个轴。现在np.ndarray
和np.ma.MaskedArray
都公开了一个.mT
属性,并且还有一个匹配的新numpy.matrix_transpose
函数。
(gh-23762)
用于numpy.linalg
的数组 API 兼容函数#
添加了六个新函数和两个别名,以提高numpy.linalg
与数组 API 标准的兼容性
numpy.linalg.matrix_norm
- 计算矩阵(或矩阵堆栈)的矩阵范数。numpy.linalg.vector_norm
- 计算向量(或向量批次)的向量范数。numpy.vecdot
- 计算两个数组的(向量)点积。numpy.linalg.matrix_transpose
-numpy.matrix_transpose
的别名。(gh-25155)
numpy.linalg.outer
已添加。它计算两个向量的外积。它与numpy.outer
的不同之处在于它只接受一维数组。此函数与数组 API 标准兼容。(gh-25101)
numpy.linalg.cross
已添加。它计算两个(三维向量数组)的叉积。它与numpy.cross
的不同之处在于它只接受三维向量。此函数与数组 API 标准兼容。(gh-25145)
用于var
和std
的correction
参数#
一个correction
参数已添加到var
和std
,它是ddof
的数组 API 标准兼容替代方案。由于两个参数都具有类似的目的,因此一次只能提供其中一个。
(gh-25169)
ndarray.device
和ndarray.to_device
#
一个ndarray.device
属性和ndarray.to_device
方法已添加到numpy.ndarray
,以实现数组 API 标准兼容性。
此外,device
关键字仅参数已添加到:asarray
、arange
、empty
、empty_like
、eye
、full
、full_like
、linspace
、ones
、ones_like
、zeros
和zeros_like
。
对于所有这些新参数,只支持device="cpu"
。
(gh-25233)
StringDType 已添加到 NumPy#
我们添加了一种新的可变宽度 UTF-8 编码字符串数据类型,它实现了“Python 字符串的 NumPy 数组”,包括对用户提供的缺失数据哨兵的支持。它旨在作为使用对象数据类型的 Python 字符串数组和缺失数据哨兵的直接替代品。有关更多详细信息,请参阅NEP 55和文档。
(gh-25347)
用于cholesky
和pinv
的新关键字#
upper
和rtol
关键字分别已添加到numpy.linalg.cholesky
和numpy.linalg.pinv
,以提高数组 API 标准兼容性。
对于pinv
,如果既未指定rcond
也未指定rtol
,则使用rcond
的默认值。我们计划在将来弃用和删除rcond
。
(gh-25388)
用于sort
、argsort
和linalg.matrix_rank
的新关键字#
添加了新的关键字参数以提高数组 API 标准兼容性
rtol
已添加到matrix_rank
。
(gh-25437)
用于字符串 ufuncs 的新 numpy.strings
命名空间#
NumPy 现在将一些字符串操作实现为 ufuncs。旧的 np.char
命名空间仍然可用,并且在可能的情况下,该命名空间中的字符串操作函数已更新为使用新的 ufuncs,从而大幅提高了它们的性能。
在可能的情况下,我们建议更新代码以使用 np.strings
中的函数,而不是 np.char
。将来,我们可能会弃用 np.char
,转而使用 np.strings
。
(gh-25463)
numpy.fft
支持不同的精度和就地计算#
numpy.fft
中的各种 FFT 例程现在根据输入精度以浮点、双精度或长双精度精度进行本机计算,而不是始终以双精度精度进行计算。因此,单精度计算将变得不太精确,而长双精度计算将变得更加精确。输出数组的数据类型现在将相应调整。
此外,所有 FFT 例程都获得了 out
参数,可用于就地计算。
(gh-25536)
configtool 和 pkg-config 支持#
提供了一个新的 numpy-config
CLI 脚本,可以查询 NumPy 版本以及使用 NumPy C API 所需的编译标志。这将使构建系统能够更好地支持将 NumPy 用作依赖项。此外,现在还包含了 Numpy 中的 numpy.pc
pkg-config 文件。为了找到其位置以与 PKG_CONFIG_PATH
一起使用,请使用 numpy-config --pkgconfigdir
。
(gh-25730)
主命名空间中的数组 API 标准支持#
现在,主 numpy
命名空间支持数组 API 标准。有关详细信息,请参阅 数组 API 标准兼容性。
(gh-25911)
改进#
字符串现在受 any
、all
和逻辑 ufuncs 支持。#
(gh-25651)
作为 memmap
的形状参数的整数序列#
现在可以使用任何整数序列(例如整数列表或 numpy 数组)作为 shape
参数来创建 numpy.memmap
。以前,只有元组和 int 类型可以在不引发错误的情况下使用。
(gh-23729)
errstate
现在更快,并且是上下文安全的#
numpy.errstate
上下文管理器/装饰器现在更快,并且更安全。以前,它不是上下文安全的,并且存在(罕见)的线程安全问题。
(gh-23936)
使用 Highway 的 VQSort 提高了 AArch64 快速排序速度#
Google Highway 库的首次引入,在 AArch64 上使用 VQSort。执行时间在某些情况下提高了 16 倍,请参阅 PR 以查看基准测试结果。将来将扩展到其他平台。
(gh-24018)
复数类型 - 底层 C 类型更改#
NumPy 的所有复数类型的底层 C 类型已更改为使用 C99 复数类型。
虽然此更改不会影响复数类型的内存布局,但它会更改用于直接检索或写入复数实部或虚部的 API,因为直接字段访问(如
c.real
或c.imag
)不再是选项。现在,您可以使用numpy/npy_math.h
中提供的实用程序来执行这些操作,例如npy_cdouble c; npy_csetreal(&c, 1.0); npy_csetimag(&c, 0.0); printf("%d + %di\n", npy_creal(c), npy_cimag(c));
为了简化跨版本兼容性,已添加了等效宏和兼容性层,下游软件包可以使用它们来继续支持 NumPy 1.x 和 2.x。有关更多信息,请参阅 复数支持。
numpy/npy_common.h
现在包含complex.h
,这意味着complex
现在是保留关键字。
(gh-24085)
iso_c_binding
支持以及针对 f2py
的改进的公共块#
以前,用户必须定义自己的自定义 f2cmap
文件才能使用 Fortran2003 iso_c_binding
内在模块定义的类型映射。现在,这些类型映射受 f2py
本机支持。
(gh-24555)
f2py
现在可以处理具有来自模块的 kind
规范的 common
块。这进一步扩展了 iso_fortran_env
和 iso_c_binding
等内在函数的可用性。
(gh-25186)
在类似 assert_equal
的函数的第三个参数上自动调用 str
#
现在,类似于 assert_equal
的函数的第三个参数会自动调用 str
。这样,它就模仿了内置的 assert
语句,其中 assert_equal(a, b, obj)
的作用类似于 assert a == b, obj
。
(gh-24877)
在 isclose
、allclose
中支持类似数组的 atol
/rtol
#
现在,isclose
和 allclose
中的关键字 atol
和 rtol
接受标量和数组。如果给出数组,则它必须广播到前两个数组参数的形状。
(gh-24878)
测试函数中一致的失败消息#
以前,一些 numpy.testing
断言会打印将实际结果和期望结果称为 x
和 y
的消息。现在,这些值始终被称为 ACTUAL
和 DESIRED
。
(gh-24931)
n-D FFT 变换允许 s[i] == -1
#
现在,fftn
、ifftn
、rfftn
、irfftn
、fft2
、ifft2
、rfft2
和 irfft2
函数现在沿轴 i
使用整个输入数组,如果 s[i] == -1
,与数组 API 标准一致。
(gh-25495)
针对有限 API 保护 PyArrayScalar_VAL 和 PyUnicodeScalarObject#
PyUnicodeScalarObject
持有一个 PyUnicodeObject
,在使用 Py_LIMITED_API
时,它不可用。添加保护以隐藏它,因此也使 PyArrayScalar_VAL
宏隐藏。
(gh-25531)
更改#
np.gradient()
现在返回元组,而不是列表,这使得返回值不可变。(gh-23861)
np.errstate
现在是完全上下文和线程安全的,因此现在只能进入一次。np.setbufsize
现在与np.errstate()
绑定:退出np.errstate
上下文也将重置bufsize
。(gh-23936)
引入了新的公共
np.lib.array_utils
子模块,它目前包含三个函数:byte_bounds
(从np.lib.utils
移动)、normalize_axis_tuple
和normalize_axis_index
。(gh-24540)
将
numpy.bool
作为 NumPy 布尔数据类型的新的规范名称引入,并使numpy.bool_
成为它的别名。请注意,在 NumPy 1.24 之前,np.bool
是 Python 内置的bool
的别名。新的名称有助于数组 API 标准兼容性,并且是一个更直观的名称。(gh-25080)
dtype.flags
值以前存储为带符号整数。这意味着对齐的 dtype 结构标志会导致设置负标志 (-128 而不是 128)。现在,此标志存储为无符号(正数)。手动检查标志的代码可能需要进行调整。这可能包括使用 Cython 0.29.x 编译的代码。(gh-25816)
NumPy 标量的表示形式已更改#
根据 NEP 51,标量表示形式已更新,包括类型信息,以避免与 Python 标量混淆。
标量现在以 np.float64(3.0)
的形式打印,而不是仅仅 3.0
。这可能会破坏将数字表示(例如,存储到文件)存储的工作流程,使其更难阅读。它们应存储为显式字符串,例如使用 str()
或 f"{scalar!s}"
。目前,受影响的用户可以使用 np.set_printoptions(legacy="1.25")
来获取旧的行为(可能有一些例外)。如果代码片段被测试,下游项目的文档可能需要更大的更新。我们正在努力为 doctest-plus 提供工具来促进更新。
(gh-22449)
NumPy 字符串的真值已更改#
NumPy 字符串以前在定义字符串是否为 True
或 False
方面不一致,并且该定义与 Python 使用的定义不匹配。字符串现在被认为在非空时为 True
,在为空时为 False
。这改变了以下不同的情况
从字符串到布尔的强制转换以前大致等效于
string_array.astype(np.int64).astype(bool)
,这意味着只有有效的整数才能被强制转换。现在,"0"
的字符串将被认为是True
,因为它是非空的。如果您需要旧的行为,您可以使用上述步骤(先转换为整数)或string_array == "0"
(如果输入始终是0
或1
)。要在旧的 NumPy 版本上获得新结果,请使用string_array != ""
。np.nonzero(string_array)
以前忽略空格,因此只有空格的字符串被认为是False
。现在空格被认为是True
。
此更改不影响 np.loadtxt
、np.fromstring
或 np.genfromtxt
。前两个仍然使用整数定义,而 genfromtxt
继续匹配 "true"
(忽略大小写)。但是,如果 np.bool_
用作转换器,结果将发生变化。
该更改确实影响了 np.fromregex
,因为它使用直接赋值。
(gh-23871)
在 var 和 std 函数中添加了 mean
关键字#
通常,当需要标准差时,也需要均值。方差和均值也是如此。到目前为止,均值被计算了两次,这里对 var
和 std
函数进行的更改允许将预先计算的均值作为关键字参数传入。有关详细信息和说明速度提升的示例,请参阅文档字符串。
(gh-24126)
在使用时区构建时删除 datetime64 弃用警告#
现在,numpy.datetime64
方法在提供的时间日期字符串中包含时区时会发出 UserWarning 而不是 DeprecationWarning。
(gh-24193)
现在,在 64 位 Windows 上,默认整数数据类型为 64 位#
现在,所有 64 位系统上的默认 NumPy 整数为 64 位,因为 Windows 上的 32 位默认值历史上是问题的常见来源。大多数用户应该不会注意到这一点。主要问题可能发生在与用编译语言(如 C)编写的库进行交互的代码中。有关更多信息,请参阅 Windows 默认整数。
(gh-24224)
将 numpy.core
重命名为 numpy._core
#
访问 numpy.core
现在会发出 DeprecationWarning。在实践中,我们发现大多数 numpy.core
的下游使用是为了访问在主 numpy
命名空间中可用的功能。如果您出于某种原因在 numpy.core
中使用主 numpy
命名空间中不可用的功能,这意味着您可能正在使用私有 NumPy 内部函数。您仍然可以通过 numpy._core
访问这些内部函数,而不会发出弃用警告,但我们不对 NumPy 内部函数提供任何向后兼容性保证。如果您认为出现错误并且需要公开某些内容,请打开问题。
(gh-24634)
以前通过 NPY_RELAXED_STRIDES_DEBUG
环境变量或 -Drelaxed-strides-debug
配置设置标志启用的“宽松步幅”调试构建选项已被删除。
(gh-24717)
重新定义 np.intp
/np.uintp
(几乎从不更改)#
由于这些类型的实际使用几乎总是与 size_t
/Py_ssize_t
的使用匹配,因此现在 C 中的定义就是如此。以前,它与 intptr_t
和 uintptr_t
匹配,这通常会微妙地不正确。这对大多数机器没有影响,因为这些类型的尺寸仅在极少数平台上有所不同。
但是,这意味着
指针可能不再适合
intp
类型的数组。但是,仍然可以使用p
和P
字符代码。在 C 中,可以通过
PyArray_DescrFromType('p')
以跨平台的方式创建intptr_t
或uintptr_t
类型的数组。引入了新的字符代码
nN
。现在,在解析为
npy_intp
类型参数时,使用 Python C-API 函数是正确的。
(gh-24888)
numpy.fft.helper
已变为私有#
numpy.fft.helper
已重命名为 numpy.fft._helper
,以表明它是一个私有子模块。它导出的所有公共函数都应从 numpy.fft
访问。
(gh-24945)
numpy.linalg.linalg
已变为私有#
numpy.linalg.linalg
已重命名为 numpy.linalg._linalg
,以表明它是一个私有子模块。它导出的所有公共函数都应从 numpy.linalg
访问。
(gh-24946)
超出范围的轴不等于 axis=None
#
在某些情况下,axis=32
或对于连接任何大值都与 axis=None
相同。除了 concatenate
之外,这已弃用。任何超出范围的轴值现在都会报错,请确保使用 axis=None
。
(gh-25149)
针对 array
和 asarray
构造函数的新的 copy
关键字含义#
现在,numpy.array
和 numpy.asarray
支持 copy
参数的三个值
None
- 仅在必要时才会进行复制。True
- 始终进行复制。False
- 从不进行复制。如果需要复制,则会引发ValueError
。
False
的含义已更改,因为它现在在需要复制时会引发异常。
(gh-25168)
现在,__array__
特殊方法接受一个 copy
关键字参数。#
在 NumPy 将 copy
传递给 __array__
特殊方法的情况下,如果它被设置为非默认值(例如,在调用 np.asarray(some_object, copy=False)
时)。当前,如果在此之后引发了意外的关键字参数错误,NumPy 将打印警告并尝试在没有 copy
关键字参数的情况下重试。实现 __array__
协议的对象的实现应接受一个 copy
关键字参数,其含义与传递给 numpy.array
或 numpy.asarray
时相同。
(gh-25168)
使用带逗号的字符串初始化 numpy.dtype
的清理#
对带逗号的字符串的解释略有变化,即现在,尾随逗号将始终创建一个结构化数据类型。例如,以前 np.dtype("i")
和 np.dtype("i,")
被视为相同,现在 np.dtype("i,")
将创建一个结构化数据类型,带有一个字段。这类似于 np.dtype("i,i")
创建一个结构化数据类型,带有两个字段,并且使行为与元组的预期行为一致。
同时,使用带括号的单个数字来表示子数组形状的做法(如在 np.dtype("(2)i,")
中)已弃用。相反,应使用 np.dtype("(2,)i")
或 np.dtype("2i")
。最终,使用括号中的数字将引发异常,就像在没有逗号的情况下进行初始化一样,例如 np.dtype("(2)i")
。
(gh-25434)
复数符号计算方法的更改#
按照数组 API 标准,复数符号现在计算为 z / |z|
(而不是相当没有逻辑的情况,在这种情况下,实部的符号被采用,除非实部为零,在这种情况下,虚部的符号被返回)。与实数一样,如果 z==0
,则返回零。
(gh-25441)
返回数组列表的函数的返回类型#
返回 ndarray 列表的函数已更改为改为返回 ndarray 元组。无论何时返回数组序列,都始终返回元组,这使得 JIT 编译器(如 Numba)以及某些情况下的静态类型检查器更容易支持这些函数。已更改的函数为:atleast_1d
、atleast_2d
、atleast_3d
、broadcast_arrays
、meshgrid
、ogrid
、histogramdd
。
np.unique
return_inverse
多维输入的形状#
当将多维输入传递给 np.unique
且 return_inverse=True
时,unique_inverse
输出现在具有这样的形状,即可以使用 np.take(unique, unique_inverse)
直接重建输入,当 axis=None
时,否则可以使用 np.take_along_axis(unique, unique_inverse, axis=axis)
。
注意
此更改已在 2.0.1 中恢复,但 axis=None
除外。正确的重建始终是 np.take(unique, unique_inverse, axis=axis)
。当需要支持 2.0.0 时,将 unique_inverse.reshape(-1)
添加到代码中。
any
和 all
为对象数组返回布尔值#
any
和 all
函数和方法现在也为对象数组返回布尔值。以前,它们进行的缩减类似于 Python or
和 and
运算符,它们计算结果为其中一个参数。可以使用 np.logical_or.reduce
和 np.logical_and.reduce
来实现以前的行为。
(gh-25712)
np.can_cast
无法在 Python int、float 或 complex 上调用#
np.can_cast
无法再使用 Python int、float 或 complex 实例调用。这是因为 NEP 50 意味着 can_cast
的结果不能依赖于传入的值。不幸的是,对于 Python 标量,是否应将强制转换视为 "same_kind"
或 "safe"
可能取决于上下文和值,因此目前尚未实现。在某些情况下,这意味着您可能需要为以下内容添加特定的路径:if type(obj) in (int, float, complex): ...
。
(gh-26393)