python - Python 对象未使用 C API 完全初始化
问题描述
在以下场景中,该对象不打算在 Python 中实例化(因此没有tp_new
or tp_init
)。我相信,将 ThingType 作为函数调用会PyObject_CallObject
导致 in 中的段错误_PyObject_FastCallDict
,因为没有构造函数。
使用 CreatePythonThing 创建对象后,get_height
除非应用变通方法,否则不会设置该函数 - 调用dir(thing)
,作为副作用初始化对象的属性。解决方法已经存在于CreatePythonThing
.
#include <Python.h>
typedef struct {
PyObject_HEAD
/* Type-specific fields go here. */
Eval *eval;
} Thing;
static PyObject* ThingGetHeight(PyObject* self, PyObject* args)
{
return PyLong_FromLong(1);
}
static PyMethodDef ThingMethods[] = {
{"get_height", ThingGetHeight, METH_NOARGS, "Get thing height"},
{NULL, NULL, 0, NULL} /* Sentinel */
};
static PyTypeObject ThingType = {
PyVarObject_HEAD_INIT(NULL, 0)
"thing.Thing", /* tp_name */
sizeof(Thing), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
"Thing", /* tp_doc */
0, 0, 0, 0, 0, 0,
ThingMethods, /* tp_methods */
};
Thing* CreatePythonThing(Eval *eval)
{
Thing* obj = PyObject_New(Thing, &ThingType);
obj->eval = eval;
obj = (Thing*) PyObject_Init((PyObject*) obj, &ThingType);
// I don't understand why, but the above does not fully initialize the object. The method
// table is not set. Calling `dir` on the object causes it to be initialized, so this is
// a workaround.
PyObject_Dir((PyObject*) obj);
return obj;
}
解决方案
正如 DavidW 的评论一样,我PyType_Ready(&ThingType);
的全局初始化程序中缺少我。
推荐阅读
- windows - 桌面上的命令行
- python - Python程序绘制覆盖在jpg地图上的一组X,Y点并通过鼠标单击删除一些点(基于地图上的特征)
- python - 使用来自客户表(mysql)的凭据的 Django 登录身份验证不起作用
- python - 使用 keras 模型预测单个记录的结果
- traefik - 本机兼容的软件是什么意思?
- javascript - 反应备忘录不渲染组件
- angular - 我可以在不同页面上为同一个 Angular 模块设置不同的引导入口点吗?
- swift - Alamofire 请求调用:参数、标题和正文不起作用
- python - 如何使用不断更新的 CSV 文件中的随机值实时绘制圆圈?
- mysql - Spring Boot / MySQL 和 Docker 问题