这个问题稍微突出了上一个问题:Accessing the underlying struct of a PyObject
除了我的版本,我想知道如何将Point结构的字段公开为我的新类型的成员。
我已经到处寻找我能想到的地方,阅读了大量的Python扩展示例并阅读了许多教程,文档等等,并且无法找到一种干净的方法来实现这一目标。
下面是我想要做的一个例子。我有一些内部结构,我想通过Python扩展来公开,但我不想在我的代码中重新定义结构。似乎问题的主要区域是PyMemeberDef定义...... Point结构的上下文中Point结构中x或y的偏移是什么?
非常感谢任何帮助,谢谢。
#include <Python.h>
#include <structmember.h>
// This is actually defined elsewhere in someone else's code.
struct Point {
int x;
int y;
};
struct PointObject {
PyObject_HEAD
struct Point* my_point;
int z;
};
static PyMemberDef point_members[] = {
{"z", T_INT, offsetof(struct PointObject, z), 0, "z field"},
{"x", T_INT, offsetof(???), 0, "point x field"},
{"y", T_INT, offsetof(???), 0, "point y field"},
{NULL}
};
static PyTypeObject PointType = {
PyObject_HEAD_INIT(NULL)
.tp_name = "Point",
.tp_basicsize = sizeof(PointObject),
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = "Point objects",
.tp_members = point_members,
.tp_init = (initproc)point_init,
};
...
PyMODINIT_FUNC
initMainModule(void)
{
PyObject *m = Py_InitModule(MODULE, NULL);
// Register PointType
PointType.tp_new = PyType_GenericNew;
if (PyType_Ready(&PointType) < 0)
return;
Py_INCREF(&PointType);
PyModule_AddObject(m, "Point", (PyObject *)&PointType);
...
}
答案 0 :(得分:2)
我强烈建议阅读http://docs.python.org/release/2.6/_sources/extending/newtypes.txt,特别是“提供更好的数据属性控制”一节。
阅读本文之后,似乎可以通过为Point结构中的特定成员定义setter / getters的集合来实现此目的。对于像这样简单的事情来说,这似乎有点矫枉过正,但似乎工作得很好。
下面是一个关于如何为Point的'x'字段执行此操作的示例,基于将以下代码添加到上一个示例中:
static PyGetSetDef point_getset[] = {
{"x", (getter)point_get_x, (setter)point_set_x, "", NULL},
{NULL}
};
static PyObject*
point_get_x(struct PointObject *self, void *closure)
{
return Py_BuildValue("i", self->my_point->x);
}
static int
point_set_x(struct PointObject *self, PyObject *value, void *closure)
{
PyErr_SetString(PyExc_TypeError, "Attribute is read-only!");
return -1;
}
最后,将point_getset结构添加到先前定义的PyTypeObject结构中的tp_getset字段。应该注意的是,对于简单的情况,您仍然可以在传统的PyMemberDef结构中定义成员。