You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何现代化改造使用已弃用NumPy C API的Python扩展代码

代码适配改造

你看到的这个警告不是说你代码里用了已经被弃用的API,只是NumPy头文件默认开启了旧版API兼容,提示你显式声明目标API版本,来关闭兼容层、消除警告。

你现有代码的核心API调用(PyArray_SimpleNew、PyArray_DATA等)本身就是NumPy 1.7之后保留的标准非弃用接口,只需要做少量调整就能完全符合现代API规范:

  • 保留NPY_NO_DEPRECATED_API宏定义,注意必须放在#include <numpy/arrayobject.h>之前,否则宏不会生效。如果需要适配更高版本的NumPy特性,可以把宏的取值改成对应版本,比如要适配NumPy 1.20+的API就写#define NPY_NO_DEPRECATED_API NPY_1_20_API_VERSION,指定后所有早于该版本的弃用接口都会在编译时直接报错,方便你排查旧接口调用。
  • 去掉不必要的堆内存分配:维度数组dims长度固定为2,直接在栈上分配即可,不需要手动new/delete,既减少开销也避免内存泄漏风险。
  • 补充必要的错误检查:PyArray_SimpleNew在内存不足等异常场景下会返回NULL并设置Python异常,加个判断能避免空指针崩溃。
  • 索引变量用npy_intp类型和NumPy内部的长度类型保持一致,避免跨平台时的类型不匹配问题。

改造后的完整代码如下:

#include <Python.h>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h>

PyObject* f()
{
    npy_intp dims[2] = {3, 4};
    PyObject* pyarray = PyArray_SimpleNew(2, dims, NPY_DOUBLE);
    if (!pyarray) {
        return NULL;
    }

    double* array_buffer = static_cast<double*>(PyArray_DATA(reinterpret_cast<PyArrayObject*>(pyarray)));
    for (npy_intp i = 0; i < dims[0]; ++i) {
        for (npy_intp j = 0; j < dims[1]; ++j) {
            // 保留原代码的列优先填充逻辑
            array_buffer[j * dims[0] + i] = j + 100 + i;
        }
    }

    return pyarray;
}
官方迁移参考查找方法

你可以直接在NumPy官方文档的C-API参考板块找对应内容:

  • 首先搜索NPY_NO_DEPRECATED_API关键字,对应的说明页会明确给出不同版本API的版本宏取值、每个版本标记弃用的接口列表,以及弃用接口对应的替代方案。
  • 每个C API函数的单独说明页,都会标注该接口的首次引入版本、是否被弃用、弃用版本以及推荐替代接口,编译时如果遇到具体的弃用提示,直接搜对应函数名就能拿到迁移指引。
  • 如果你是从NumPy 1.6及更早的老版本API迁移,文档里有专门的1.7版本API迁移指南,列了全量的新旧接口映射关系,可以直接对照修改。

注:如果需要使用NumPy 2.0之后的新API,只需要把宏的版本号改成NPY_2_0_API_VERSION即可,上述代码里用到的接口在2.0版本中依然是标准非弃用接口,不需要额外修改。

内容的提问来源于stack exchange,提问作者Joachim W

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 10:57:18