NumPy 2.0.0 发行说明#

NumPy 2.0.0 是自 2006 年以来的第一个主要版本.它是自上次功能版本以来 11 个月开发的成果,是 212 位贡献者在 1078 个 pull request 中共同完成的.它包含大量令人兴奋的新功能,以及 Python 和 C API 的更改.

此主要版本包括破坏性更改,这些更改不会在常规的次要(功能)版本中发生 - 包括 ABI 破坏,类型提升规则的更改以及 API 更改,这些更改可能未在 1.26.x 中发出弃用警告.除了这些发行说明之外,与如何适应 NumPy 2.0 中的更改相关的关键文档包括:

亮点#

此版本的亮点包括:

  • 新功能:

    • 一种新的可变长度字符串 dtype, StringDType 和一个新的 numpy.strings 命名空间,其中包含用于字符串操作的高性能 ufuncs,

    • 在所有 numpy.fft 函数中支持 float32longdouble ,

    • 在主 numpy 命名空间中支持 array API 标准.

  • 性能提升:

    • 排序函数( sort , argsort , partition , argpartition )已通过使用 Intel x86-simd-sort 和 Google Highway 库加速,并且可能会看到很大的(特定于硬件的)加速,

    • macOS Accelerate 支持和 macOS >=14 的二进制 wheels,显着提高了 macOS 上线性代数运算的性能,并且 wheels 的大小约为原来的 3 倍,

    • numpy.char 固定长度字符串操作已通过实现 ufuncs 加速,这些 ufuncs 除了支持固定长度字符串 dtypes 外,还支持 StringDType ,

    • 一个新的追踪和自省 API, opt_func_info ,用于确定哪些硬件特定的内核可用以及将被分派到.

    • numpy.save 现在使用 pickle 协议版本 4 来保存具有 object dtype 的数组,这允许 pickle 对象大于 4GB,并为大型数组提高约 5% 的保存速度.

  • Python API 改进:

    • 公共 API 和私有 API 之间有明确的划分,具有新的 module structure ,并且每个公共函数现在都可以在一个地方找到,

    • 许多不推荐使用的函数和别名已被删除.这应该使学习和使用 NumPy 更加容易.主命名空间中的对象数量减少了约 10%, numpy.lib 中减少了约 80%,

    • Canonical dtype names 和一个新的 isdtype 自省函数,

  • C API 改进:

  • 改进的行为:

    • 通过采用 NEP 50 更改了类型提升行为的改进.这修复了许多用户对提升的意外,这些提升以前通常取决于输入数组的数据值,而不仅仅是它们的 dtypes.请参阅 NEP 和 NumPy 2.0 迁移指南 以获取详细信息,因为此更改可能导致输出 dtypes 的更改以及混合 dtype 操作的较低精度结果.

    • Windows 上的默认整数类型现在是 int64 而不是 int32 ,与其他平台上的行为相匹配,

    • 数组维度的最大数量从 32 更改为 64

  • 文档:

此外,NumPy 内部结构还有许多更改,包括继续将代码从 C 迁移到 C++,这将使其更容易在未来改进和维护 NumPy.

“没有免费的午餐” 定理表明,为所有这些 API 和行为改进以及更好的未来可扩展性付出代价.这个代价是:

  1. 向后兼容性.Python 和 C API 都有大量重大更改.在大多数情况下,都有明确的错误消息,会告知用户如何调整他们的代码.但是,行为也发生了变化,对于这些变化,无法给出这样的错误消息 - 这些情况都在下面的"弃用和兼容性"部分以及 NumPy 2.0 迁移指南 中进行了介绍.

    请注意,有一个 ruff 模式可以自动修复 Python 代码中的许多问题.

  2. 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 以及相关的 ufunc 关键字参数 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 已被移除.作为移除功能的替代方案,可以使用 IDE 中提供的变量资源管理器,例如 Spyder 或 Jupyter Notebook.

    ( gh-24321 )

  • numpy.exceptions 中存在的警告和异常(例如, ComplexWarning , VisibleDeprecationWarning )不再在主命名空间中公开.

  • 多个小众枚举,过期的成员和函数已从主命名空间中移除,例如: ERR_* , SHIFT_* , np.fastCopyAndTranspose , np.kernel_version , np.numarray , np.oldnumericnp.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_docstringnp.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.recfromcsvnp.recfromtxt 已从主命名空间中移除.请使用带逗号分隔符的 np.genfromtxt 代替.

  • np.issctype , np.maximum_sctype , np.obj2sctype , np.sctype2char , np.sctypes , np.issubsctype 都已从主命名空间中移除,没有替代品,因为它们是小众成员.

  • 已弃用的 np.deprecatenp.deprecate_with_doc 已从主命名空间中移除.请使用 DeprecationWarning 代替.

  • 已弃用的 np.safe_eval 已从主命名空间中移除.请使用 ast.literal_eval 代替.

    ( gh-24376 )

  • np.find_common_type 已被移除.请使用 numpy.promote_typesnumpy.result_type 代替.要实现 scalar_types 参数的语义,请使用 numpy.result_type 并传递 0 , 0.00j 作为 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 , bytes0bool8 .

    ( gh-24807 )

  • 实验性的 numpy.array_api 子模块已被移除.请改用主 numpy 命名空间进行常规使用,或者使用单独的 array-api-strict 包,用于 numpy.array_api 主要用于的合规性测试用例.

    ( gh-25911 )

__array_prepare__ 已被移除#

UFuncs 在为普通 ufunc 调用(非广义 ufunc,归约等)运行计算之前调用 __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.deprecatenp.deprecate_with_doc 已被弃用.

    ( gh-24154 )

  • np.trapz 已被弃用.请改用 np.trapezoidscipy.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 )

  • 关键字参数 xy 与函数 assert_array_equalassert_array_almost_equal 一起使用已被弃用.请将前两个参数改为位置参数传递.

    ( gh-24978 )

numpy.fft 关于参数中包含 None 值的 n-D 变换的弃用#

使用 fftn , ifftn , rfftn , irfftn , fft2 , ifft2 , rfft2irfft2 ,且将 s 参数设置为非 None 值,并将 axes 参数设置为 None 已被弃用,这与 array API 标准一致.要保留当前行为,对于维度为 k 的数组,请将序列 [0, …, k-1] 传递给 axes .

此外,将包含 None 值的数组传递给 s 已被弃用,因为该参数在 NumPy 文档和 array API 规范中都被记录为接受整数序列.要使用相应 1-D 变换的默认行为,请传递与其 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 弃用已过期,现已删除.使用 tracemallocnp.lib.tracemalloc_domain 域.(在 NumPy 1.23 中已弃用)

    ( gh-23921 )

  • set_numeric_ops 以及 C 函数 PyArray_SetNumericOpsPyArray_GetNumericOps 的弃用已过期,这些函数已删除.(在 NumPy 1.16 中已弃用)

    ( gh-23998 )

  • fasttake , fastclipfastputmask 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 属性,并且会引发异常.

  • 如果 width 太小, np.binary_repr(a, width) 将引发异常.

  • PyArray_DescrFromType() 中使用 NPY_CHAR 将引发异常,请改用 NPY_STRING NPY_UNICODENPY_VSTRING .

    ( gh-25794 )

兼容性说明#

loadtxtgenfromtxt 默认编码已更改#

loadtxtgenfromtxt 现在都默认为 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 .它还使用了几个过于脆弱而无法移植到与 meson 一起使用的 np.distutils 功能.

  • 强烈建议用户将对 f2py.compile 的调用替换为对 subprocess.run("python", "-m", "numpy.f2py",... 的调用,并使用环境变量与 meson 交互. Native files 也是一个选项.

    ( gh-25193 )

排序函数行为的细微变化#

由于算法更改和 SIMD 代码的使用,与 1.26.x 相比,使用非稳定方法的排序函数在 2.0.0 中可能会返回略有不同的结果.这包括 argsortargpartition 的默认方法.

消除了 np.solve 中广播时的歧义#

ba 少 1 个维度时, 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_MINPyArray_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 )

  • 已从 PyArray_Descr 中删除 ->f slot.如果您使用此 slot,请使用 PyDataType_GetArrFuncs 替换对它的访问(请参阅其文档和 NumPy 2.0 迁移指南 ).在某些情况下,使用其他函数(如 PyArray_GETITEM )可能是一种替代方法.

  • PyArray_GETITEMPyArray_SETITEM 现在需要导入 NumPy API 表才能使用,并且不再在 ndarraytypes.h 中定义.

    ( gh-25812 )

  • 由于运行时依赖性,访问 dtype 标志的功能的定义已从 numpy/ndarraytypes.h 移动,并且仅在包含 numpy/ndarrayobject.h (因为它需要 import_array() )之后才可用.这包括 PyDataType_FLAGCHK , PyDataType_REFCHKNPY_BEGIN_THREADS_DESCR .

  • PyArray_Descr 上的 dtype 标志现在必须通过 PyDataType_FLAGS 内联函数访问,才能与 1.x 和 2.x 兼容.此函数在 npy_2_compat.h 中定义,以允许向后移植.大多数或所有用户应使用 PyDataType_FLAGCHK ,它在 1.x 上可用,并且不需要向后移植.Cython 用户应使用 Cython 3.否则,访问将通过 Python,除非他们改用 PyDataType_FLAGCHK .

    ( gh-25816 )

C API 和 Cython 绑定中公开的日期时间功能#

函数 NpyDatetime_ConvertDatetime64ToDatetimeStruct , NpyDatetime_ConvertDatetimeStructToDatetime64 , NpyDatetime_ConvertPyDateTimeToDatetimeStruct , NpyDatetime_GetDatetimeISO8601StrLen , NpyDatetime_MakeISO8601DatetimeNpyDatetime_ParseISO8601Datetime 已添加到 C API,以方便在外部库中在字符串,Python 日期时间和 NumPy 日期时间之间进行转换.

( gh-21199 )

广义 ufunc C API 的常量正确性#

NumPy C API 中用于构造广义 ufunc 的函数( PyUFunc_FromFuncAndData , PyUFunc_FromFuncAndDataAndSignature , PyUFunc_FromFuncAndDataAndSignatureAndIdentity )接受 typesdata 参数,这些参数不会被 NumPy 内部修改.与 namedoc 参数一样,第三方 Python 扩展模块可能会从静态常量提供这些参数. typesdata 参数现在是常量正确的:它们分别声明为 const char typesvoid const data .C 代码不应受到影响,但 C++ 代码可能会受到影响.

( gh-23847 )

更大的 NPY_MAXDIMSNPY_MAXARGS ,引入了 NPY_RAVEL_AXIS#

NPY_MAXDIMS 现在是 64,您可能需要检查它的使用情况.这通常用于堆栈分配,增加应该是安全的.但是,我们通常鼓励删除任何对 NPY_MAXDIMSNPY_MAXARGS 的使用,以便最终完全删除该约束.对于转换助手和 C-API 函数(例如 take 等镜像 Python 函数), 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 和用于导入 numpy C API 的普通 import_array() 机制在 NumPy 外部编写自定义 DType.

有关 API 的更多详细信息,请参见 自定义数据类型 .与新功能一样,请报告您在实现或使用新的 DType 时遇到的任何错误.与 DType 一起使用的下游 C 代码可能需要更新才能与新的 DType 正确工作.

( gh-25754 )

新的 C-API 导入函数#

我们现在添加了 PyArray_ImportNumPyAPIPyUFunc_ImportUFuncAPI 作为静态内联函数来导入 NumPy C-API 表.与 import_arrayimport_ufunc 相比,新函数有两个优势:

  • 它们检查是否已经执行了导入,如果未执行,则重量轻,允许明智地添加它们(尽管在大多数情况下这不是首选).

  • 旧机制是包含 return 语句的宏,而不是函数.

PyArray_ImportNumPyAPI() 函数包含在 npy_2_compat.h 中,以便更简单地进行反向移植.

( gh-25866 )

通过函数访问结构化的 dtype 信息#

dtype 结构的字段 c_metadata , names , fieldssubarray 现在必须通过与这些名称相同的新函数来访问,例如 PyDataType_NAMES .直接访问这些字段是无效的,因为它们并非对所有 PyArray_Descr 实例都存在.保留了 metadata 字段,但宏版本也应该是首选.

( gh-25802 )

描述符 elsizealignment 访问#

除非仅使用 NumPy 2 支持进行编译,否则现在必须通过 PyDataType_ELSIZE , PyDataType_SET_ELSIZEPyDataType_ALIGNMENT 访问 elsizealignment 字段.如果描述符附加到数组,我们建议使用 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_handlefperrPyUFunc_checkfperr 已被移除.如果需要,可以恢复一个新的向后兼容的函数来引发浮点错误.移除原因:没有已知的用户,并且这些函数会使 with np.errstate() 的修复变得更加困难).

    ( gh-23922 )

  • 自 NumPy 1.7 起已弃用的 API 的一部分 numpy/old_defines.h 已被移除.这移除了 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_REFCNTNPY_REFCOUNT 已移除.请改用 Py_REFCNT .

    ( gh-25156 )

  • PyArrayFlags_TypePyArray_NewFlagsObject 以及 PyArrayFlagsObject 现在是私有的. 没有已知的用例; 如果需要,请使用 Python API.

  • PyArray_MoveInto , PyArray_CastTo , PyArray_CastAnyTo 已移除,使用 PyArray_CopyInto ,如果绝对需要,可以使用 PyArray_CopyAnyInto (后者执行平面复制).

  • PyArray_FillObjectArray 已移除,它唯一真正的用途是实现 np.empty . 创建一个新的空数组或使用 PyArray_FillWithScalar() (减少现有对象的引用计数).

  • PyArray_CompareUCS4PyArray_CompareString 已移除. 使用标准的 C 字符串比较函数.

  • PyArray_ISPYTHON 已移除,因为它具有误导性,没有已知的用例,并且易于替换.

  • PyArray_FieldNames 已移除,因为不清楚它有什么用处. 它在某些可能的用例中也具有不正确的语义.

  • PyArray_TypestrConvert 已移除,因为它似乎用词不当,并且不太可能被任何人使用. 如果您知道大小或仅限于几种类型,请直接显式使用它,否则通过 Python 字符串.

    ( gh-25292 )

  • PyDataType_GetDatetimeMetaData 已移除,至少从 NumPy 1.7 开始,它实际上并没有做任何事情.

    ( gh-25802 )

  • PyArray_GetCastFunc 已移除. 请注意,自定义的旧版用户 dtypes 仍然可以提供 castfunc 作为其实现,但是现在已删除对它们的任何访问. 原因是 NumPy 多年来从未在内部使用过这些函数. 如果您使用简单的数字类型,请直接使用 C 转换. 如果您需要替代方案,请告诉我们,以便我们可以创建新的 API,例如 PyArray_CastBuffer() ,它可以根据 NumPy 版本使用旧的或新的转换函数.

    ( gh-25161 )

新特性#

np.add 被扩展为支持 unicodebytes dtypes.#

一个新的 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#

已添加对更新的 Accelerate BLAS/LAPACK 库的支持,包括 macOS 13.3 中的 ILP64(64 位整数)支持. 这带来了 arm64 支持,以及常用线性代数运算高达 10 倍的显著性能提升. 如果在构建时选择了 Accelerate,或者未进行显式的 BLAS 库选择,则如果可用,将自动使用 13.3+ 版本.

( gh-24053 )

二进制 wheels 也可用. 在 macOS >=14.0 上,从 PyPI 安装 NumPy 的用户将获得针对 Accelerate 而不是 OpenBLAS 构建的 wheels.

( gh-25255 )

用于分位数和百分位数函数权重的选项#

weights 关键字现在可用于 quantile , percentile , nanquantilenanpercentile . 只有 method="inverted_cdf" 支持权重.

( gh-24254 )

改进的 CPU 优化跟踪#

现在提供了一种新的追踪器机制,可以跟踪 NumPy 库中每个优化函数(即使用特定于硬件的 SIMD 指令的函数)的已启用目标. 通过此增强功能,可以精确监控已调度函数的已启用 CPU 调度目标.

一个新的名为 opt_func_info 的函数已添加到新的命名空间 numpy.lib.introspect 中,提供此跟踪功能. 此函数允许您根据函数名称和数据类型签名检索有关已启用目标的信息.

( gh-24420 )

f2py 的新 Meson 后端#

编译模式下的 f2py (即 f2py -c ) 现在接受 --backend meson 选项. 这是 Python >=3.12 的默认选项. 对于旧版本的 Python, f2py 仍将默认为 --backend distutils .

为了在实际用例中支持这一点,在编译模式下 f2py 接受一个或多个 --dep 标志,这些标志映射到 meson 后端中的 dependency() 调用,并且在 distutils 后端中不执行任何操作.

仅作为代码生成器使用 f2py 的用户(即没有 -c )没有任何更改.

( gh-24532 )

f2pybind(c) 支持#

函数和子例程都可以使用 bind(c) 进行注释. f2py 将处理正确的类型映射,并为其他 C 接口保留唯一的标签.

注意:按设计, f2py 绑定不接受 bind(c, name = 'routine_name_other_than_fortran_routine') ,因为带有 namebind(c) 仅用于保证 C 和 Fortran 中的名称相同,而不是 Python 和 Fortran 中的名称.

( gh-24555 )

几个测试函数的新 strict 选项#

strict 关键字现在可用于 assert_allclose , assert_equalassert_array_less . 设置 strict=True 将禁用标量的广播行为,并确保输入数组具有相同的数据类型.

( gh-24680 , gh-24770 , gh-24775 )

添加 np.core.umath.findnp.core.umath.rfind UFuncs#

添加两个在 unicode 或字节字符串上运行的 findrfind UFuncs,它们在 np.char 中使用. 它们的操作类似于 str.findstr.rfind .

( gh-24868 )

diagonaltrace for numpy.linalg#

已添加 numpy.linalg.diagonalnumpy.linalg.trace ,它们是与数组 API 标准兼容的 numpy.diagonalnumpy.trace 变体. 它们在定义 2-D 子数组的默认轴选择方面有所不同.

( gh-24887 )

新的 longulong dtypes#

已添加 numpy.longnumpy.ulong 作为映射到 C 的 longunsigned long 的 NumPy 整数. 在 NumPy 1.24 之前, numpy.long 是 Python 的 int 的别名.

( gh-24922 )

svdvals for numpy.linalg#

已添加 numpy.linalg.svdvals . 它计算(矩阵堆栈的)奇异值. 执行 np.svdvals(x) 与调用 np.svd(x, compute_uv=False, hermitian=False) 相同. 此函数与 array API 标准兼容.

( gh-24940 )

一个新的 isdtype 函数#

添加了 numpy.isdtype ,以提供符合数组 API 标准的分类 NumPy 的 dtypes 的规范方法.

( gh-25054 )

一个新的 astype 函数#

新增了 numpy.astype ,以提供与数组 API 标准兼容的 numpy.ndarray.astype 方法的替代方案.

( 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_inverseunique_values 函数. 它们提供了具有不同标志集的 unique 的功能. 它们与数组 API 标准兼容,并且由于它们返回的数组数量不依赖于输入参数的值,因此更容易进行 JIT 编译.

( gh-25088 )

ndarray 的矩阵转置支持#

NumPy 现在支持计算数组(或数组堆栈)的矩阵转置. 矩阵转置等效于交换数组的最后两个轴. np.ndarraynp.ma.MaskedArray 现在都公开了一个 .mT 属性,并且有一个匹配的新 numpy.matrix_transpose 函数.

( gh-23762 )

numpy.linalg 的数组 API 兼容函数#

新增了六个函数和两个别名,以提高与 numpy.linalg 的数组 API 标准的兼容性:

varstdcorrection 参数#

varstd 添加了 correction 参数,它是 ddof 的数组 API 标准兼容替代方案. 由于这两个参数具有相似的用途,因此只能同时提供其中一个.

( gh-25169 )

ndarray.devicendarray.to_device#

numpy.ndarray 添加了 ndarray.device 属性和 ndarray.to_device 方法,以实现数组 API 标准兼容性.

此外, device 仅限关键字参数已添加到:asarray , arange , empty , empty_like , eye , full , full_like , linspace , ones , ones_like , zeroszeros_like .

对于所有这些新参数,仅支持 device="cpu" .

( gh-25233 )

StringDType 已添加到 NumPy#

我们添加了一种新的可变宽度 UTF-8 编码字符串数据类型,实现了"Python 字符串的 NumPy 数组",包括支持用户提供的缺失数据 sentinel. 它旨在作为使用对象 dtype 的 Python 字符串数组和缺失数据 sentinel 的直接替代品. 有关更多详细信息,请参见 NEP 55the documentation .

( gh-25347 )

choleskypinv 的新关键字#

upperrtol 关键字分别被添加到 numpy.linalg.choleskynumpy.linalg.pinv ,以提高数组 API 标准的兼容性.

对于 pinv ,如果既没有指定 rcond 也没有指定 rtol ,则使用 rcond 的默认值.我们计划在未来弃用并移除 rcond .

( gh-25388 )

sort , argsortlinalg.matrix_rank 的新关键字#

添加了新的关键字参数,以提高数组 API 标准的兼容性:

( 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 例程现在根据输入精度,以 float,double 或 long double 精度进行原生计算,而不是始终以 double 精度进行计算.因此,对于单精度,计算精度会降低,而对于 long double 精度,计算精度会提高.输出数组的数据类型现在将相应地进行调整.

此外,所有 FFT 例程都获得了一个 out 参数,该参数可用于就地计算.

( gh-25536 )

configtool 和 pkg-config 支持#

现在有一个新的 numpy-config CLI 脚本可用,可以查询 NumPy 版本以及使用 NumPy C API 所需的编译标志.这将使构建系统更好地支持将 NumPy 用作依赖项.此外, numpy.pc pkg-config 文件现在包含在 Numpy 中.为了找到它与 PKG_CONFIG_PATH 一起使用的位置,请使用 numpy-config --pkgconfigdir .

( gh-25730 )

主命名空间中的 Array API 标准支持#

numpy 命名空间现在支持 array API 标准.有关详细信息,请参阅 Array API 标准兼容性 .

( gh-25911 )

改进#

any , all 和逻辑 ufuncs 现在支持字符串.#

整数序列作为 memmap 的 shape 参数#

现在可以使用任何整数序列(例如整数列表或 numpy 数组)作为 shape 参数来创建 numpy.memmap .以前,只有 tuple 和 int 类型可以在不引发错误的情况下使用.

( gh-23729 )

errstate 现在更快且上下文安全#

numpy.errstate 上下文管理器/装饰器现在更快更安全.以前,它不是上下文安全的,并且存在(罕见的)线程安全问题.

( gh-23936 )

使用 Highway 的 VQSort 提高了 AArch64 quicksort 的速度#

首次引入 Google Highway 库,在 AArch64 上使用 VQSort.在某些情况下,执行时间提高了 16 倍,有关基准测试结果,请参见 PR.将来将扩展到其他平台.

( gh-24018 )

复数类型 - 底层 C 类型变更#

  • NumPy 所有复数类型的底层 C 类型已更改为使用 C99 复数类型.

  • 虽然此更改不影响复数类型的内存布局,但它更改了用于直接检索或写入复数的实部或虚部的 API,因为直接字段访问(如 c.realc.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 intrinsic 模块定义的类型映射.这些类型映射现在由 f2py 本机支持

( gh-24555 )

f2py 现在可以处理具有来自模块的 kind 规范的 common 块.这进一步扩展了诸如 iso_fortran_enviso_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#

iscloseallclose 中的关键字 atolrtol 现在同时接受标量和数组. 如果给定一个数组,则它必须广播到前两个数组参数的形状.

( gh-24878 )

测试函数中一致的失败消息#

以前,某些 numpy.testing 断言打印的消息将实际结果和期望结果称为 xy . 现在,这些值始终被称为 ACTUALDESIRED .

( gh-24931 )

n-D FFT 变换允许 s[i] == -1#

如果 s[i] == -1 ,则 fftn , ifftn , rfftn , irfftn , fft2 , ifft2 , rfft2irfft2 函数现在沿着轴 i 使用整个输入数组,与数组 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_tuplenormalize_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" (如果输入始终只有 01 ).要在旧的 NumPy 版本上获得新的结果,请使用 string_array != "" .

  • np.nonzero(string_array) 以前忽略空格,因此仅包含空格的字符串被认为是 False .现在空格被认为是 True .

此更改不影响 np.loadtxt , np.fromstringnp.genfromtxt .前两个仍然使用整数定义,而 genfromtxt 继续匹配 "true" (忽略大小写).但是,如果将 np.bool_ 用作转换器,则结果将发生变化.

此更改确实会影响 np.fromregex ,因为它使用直接赋值.

(gh-23871)

为 var 和 std 函数添加了 mean 关键字#

通常,当需要标准差时,也需要平均值.方差和平均值也是如此.到现在为止,平均值会被计算两次,这里为 varstd 函数引入的更改允许将预先计算的平均值作为关键字参数传入.有关详细信息和说明加速的示例,请参见文档字符串.

(gh-24126)

删除使用时区构造时的 datetime64 弃用警告#

每当提供的 datetime 字符串中包含时区时, numpy.datetime64 方法现在发出 UserWarning 而不是 DeprecationWarning.

(gh-24193)

在 64 位 Windows 上,默认整数 dtype 现在是 64 位#

由于 Windows 上历史性的 32 位默认值是常见的问题来源,因此默认的 NumPy 整数现在在所有 64 位系统上都是 64 位的.大多数用户不应该注意到这一点.主要问题可能出现在与用编译语言(如 C)编写的库接口的代码中.有关更多信息,请参见 Windows 默认整数 .

(gh-24224)

numpy.core 重命名为 numpy._core#

访问 numpy.core 现在会发出 DeprecationWarning.在实践中,我们发现大多数对 numpy.core 的下游使用是为了访问主 numpy 命名空间中可用的功能.如果由于某种原因,您正在使用 numpy.core 中但主 numpy 命名空间中不可用的功能,这意味着您可能正在使用私有的 NumPy 内部组件.您仍然可以通过 numpy._core 访问这些内部组件,而不会收到弃用警告,但我们不为 NumPy 内部组件提供任何向后兼容性保证.如果您认为出现错误并且需要公开某些内容,请提交 issue.

(gh-24634)

"宽松步幅"调试构建选项(以前通过 NPY_RELAXED_STRIDES_DEBUG 环境变量或 -Drelaxed-strides-debug config-settings 标志启用)已删除.

(gh-24717)

重新定义 np.intp / np.uintp (几乎从不改变)#

由于这些类型的实际使用几乎总是与 size_t / Py_ssize_t 的使用相匹配,因此这现在是 C 中的定义.以前,它匹配 intptr_tuintptr_t ,这通常会稍微不正确.这对绝大多数机器没有影响,因为这些类型的大小仅在非常特殊的平台上有所不同.

但是,这意味着:

  • 指针可能不再一定适合 intp 类型的数组.但是,仍然可以使用 pP 字符代码.

  • 在 C 中,通过 PyArray_DescrFromType('p') 创建 intptr_tuintptr_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 不同#

在某些情况下,对于 concatenate , axis=32 或任何较大的值与 axis=None 相同.除了 concatenate 之外,这已被弃用.任何越界的轴值现在都会报错,请确保使用 axis=None .

( gh-25149 )

arrayasarray 构造函数中 copy 关键字的新含义#

现在 numpy.arraynumpy.asarray 支持 copy 参数的三个值:

  • None - 仅在必要时才进行复制.

  • True - 始终进行复制.

  • False - 永不进行复制.如果需要复制,则会引发 ValueError .

False 的含义发生了变化,因为如果需要复制,它现在会引发异常.

( gh-25168 )

特殊方法 __array__ 现在接受 copy 关键字参数.#

numpy.arraynumpy.asarray 中,当 copy 被设置为非默认值时,NumPy会将 copy 传递给 __array__ 特殊方法(例如,在调用 np.asarray(some_object, copy=False) 时).目前,如果在此之后引发了意外的关键字参数错误,NumPy将打印警告并重试,而不使用 copy 关键字参数.实现 __array__ 协议的对象的实现应接受一个 copy 关键字参数,其含义与传递给 numpy.arraynumpy.asarray 时相同.

( gh-25168 )

清理带有逗号的字符串初始化 numpy.dtype 的过程#

带有逗号的字符串的解释略有变化,即尾随逗号现在将始终创建一个结构化的 dtype.例如,以前 np.dtype("i")np.dtype("i,") 被视为相同,现在 np.dtype("i,") 将创建一个结构化的 dtype,只有一个字段.这类似于 np.dtype("i,i") 创建一个带有两个字段的结构化的 dtype,并使行为与元组的行为保持一致.

同时,使用括号包围的单个数字来指示子数组形状(如 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 多维输入时的形状#

当多维输入传递给带有 return_inverse=Truenp.unique 时, unique_inverse 输出现在的形状使得当 axis=None 时,可以使用 np.take(unique, unique_inverse) 直接重建输入,否则可以使用 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) 添加到代码.

( gh-25553 , gh-25570 )

anyall 为对象数组返回布尔值#

anyall 函数和方法现在也为对象数组返回布尔值.以前,它们进行归约,其行为类似于 Python orand 运算符,后者计算结果为其中一个参数.您可以使用 np.logical_or.reducenp.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 )