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

Python 3 C++扩展中DateTime对象方法调用异常问题

解决Python C++扩展中DateTime对象年份读取错误的问题

我之前开发Python扩展时也踩过这个一模一样的坑!你遇到的PyDateTime_GET_YEAR返回65535的问题,根源在于参数解析的方式不对。

问题分析

你用PyArg_ParseTuple(args, "O", &pydate)来获取参数,虽然PyDateTime_Check(pydate)能返回true(它只是检查对象的类型标识),但"O"格式码只是把PyObject指针直接赋值给pydate,并没有完成正确的类型转换——PyDateTime_DateTime结构体有特定的内存布局,直接用PyObject指针强转的话,读取年份等字段时会访问错误的内存地址,就出现了65535这种异常值(这是无符号短整型的最大值,典型的内存越界读错值的表现)。

修复方案

你需要用"O!"格式码来解析参数,它会同时检查对象类型并完成正确的指针转换。修改你的参数解析代码:

#include "Python.h"
#include "datetime.h"

static PyObject* new_func(PyObject* self, PyObject* args) {
    PyDateTime_DateTime *pydate;
    // 用O!格式,指定PyDateTime_Type来确保类型正确转换
    if(!PyArg_ParseTuple(args, "O!", &PyDateTime_Type, &pydate)){
        return NULL; // 处理参数解析失败的情况
    }

    // 现在可以正确获取年份了
    int year = PyDateTime_GET_YEAR(pydate);
    // 同理,月份、日、时分秒等字段也能正确读取
    int month = PyDateTime_GET_MONTH(pydate);
    int day = PyDateTime_GET_DAY(pydate);
    int hour = PyDateTime_DATE_GET_HOUR(pydate);

    // 后续逻辑示例:返回年份给Python端
    return PyLong_FromLong(year);
}

额外注意事项

  • 务必在模块初始化函数中调用PyDateTime_IMPORT(),不然可能会出现PyDateTime_Type未定义的问题:
    static struct PyModuleDef mymodule = {
        PyModuleDef_HEAD_INIT,
        "mymodule",
        NULL,
        -1,
        new_func_methods // 你的方法表
    };
    
    PyMODINIT_FUNC PyInit_mymodule(void) {
        PyObject* m = PyModule_Create(&mymodule);
        if (m == NULL) return NULL;
        // 初始化datetime模块,必须调用
        PyDateTime_IMPORT();
        return m;
    }
    
  • 编译时不用额外操心链接问题,用setuptools等Python扩展编译工具会自动处理头文件和依赖。

这样修改后,你再传入datetime.datetime.now(),就能正确读取年份等所有字段啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:06:15