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

如何在Python C/C++扩展中正确定义对象的__str__方法

解决C/C++ Python扩展中__str__实现无效的问题

问题根源

你遇到的问题核心在于:Python的特殊方法(如__str__)不能通过PyMethodDef方法表注册。虽然你把__str__加到了方法表里,导致直接调用myobj.__str__()能生效,但Python内置的str()函数、print()函数会优先查找自定义类型PyTypeObject结构体中的tp_str字段,而非方法表中的__str__条目,所以str(myobj)无法正常工作。

正确实现步骤

1. 在PyTypeObject中指定tp_str字段

修改你的自定义类型定义,将Foo_str函数赋值给tp_str字段,这是Python识别__str__特殊方法的标准方式:

static PyTypeObject FooType = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "mymodule.Foo",
    .tp_basicsize = sizeof(FooObject),
    .tp_flags = Py_TPFLAGS_DEFAULT,
    .tp_doc = "Foo objects",
    .tp_str = (reprfunc)Foo_str,  // 绑定__str__对应的实现函数
    .tp_methods = Foo_methods,    // 保留其他方法(如果有的话)
};

2. 从PyMethodDef中移除__str__条目

既然已经通过tp_str注册了特殊方法,无需再把__str__放到方法表里(保留也不会出错,但属于冗余操作):

static PyMethodDef Foo_methods[] = {
    // 移除__str__的注册条目
    { NULL }  /* sentinel */
};

3. 确保函数签名匹配(可选优化)

tp_str对应的函数签名是PyObject* (*reprfunc)(PyObject*),你可以调整Foo_str的签名以更贴合标准,避免类型转换的潜在问题:

static PyObject *
Foo_str(PyObject *self)
{
    // 如果需要访问FooObject的成员,可在此转换类型
    // FooObject *foo = reinterpret_cast<FooObject*>(self);
    return PyUnicode_FromFormat("bar");
}

效果验证

完成上述修改后,调用str(myobj)、print(myobj)都会正常触发Foo_str函数,输出预期的bar。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:52:17