在自定义PyTypeObject中同时使用.tp_getattro / .tp_setattro和.tp_getset,可以通过以下步骤完成:
这样,自定义类型就可以同时支持.tp_getattro / .tp_setattro和.tp_getset,实现属性的获取和设置操作。
下面是一个示例代码,演示了如何在自定义PyTypeObject中同时使用.tp_getattro / .tp_setattro和.tp_getset:
#include <Python.h>
typedef struct {
PyObject_HEAD
PyObject *data;
} CustomObject;
static PyObject *
custom_getattro(CustomObject *self, PyObject *name)
{
// 检查是否在.tp_getset定义的属性列表中
static PyGetSetDef custom_getset[] = {
{"value", (getter)custom_get_value, (setter)custom_set_value, "Custom value", NULL},
{NULL}
};
if (PyUnicode_Check(name)) {
PyGetSetDef *def;
for (def = custom_getset; def->name != NULL; def++) {
if (PyUnicode_CompareWithASCIIString(name, def->name) == 0) {
// 调用相应的getter函数返回属性值
return def->get((PyObject *)self, NULL);
}
}
}
// 调用通用的属性获取函数
return PyObject_GenericGetAttr((PyObject *)self, name);
}
static int
custom_setattro(CustomObject *self, PyObject *name, PyObject *value)
{
// 检查是否在.tp_getset定义的属性列表中
static PyGetSetDef custom_getset[] = {
{"value", (getter)custom_get_value, (setter)custom_set_value, "Custom value", NULL},
{NULL}
};
if (PyUnicode_Check(name)) {
PyGetSetDef *def;
for (def = custom_getset; def->name != NULL; def++) {
if (PyUnicode_CompareWithASCIIString(name, def->name) == 0) {
// 调用相应的setter函数设置属性值
return def->set((PyObject *)self, value, NULL);
}
}
}
// 调用通用的属性设置函数
return PyObject_GenericSetAttr((PyObject *)self, name, value);
}
static PyTypeObject CustomType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "custom.Custom",
.tp_basicsize = sizeof(CustomObject),
.tp_getattro = (getattrofunc)custom_getattro,
.tp_setattro = (setattrofunc)custom_setattro,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = "Custom objects",
};
static PyModuleDef custommodule = {
PyModuleDef_HEAD_INIT,
.m_name = "custom",
.m_size = -1,
};
PyMODINIT_FUNC
PyInit_custom(void)
{
PyObject *m;
if (PyType_Ready(&CustomType) < 0) {
return NULL;
}
m = PyModule_Create(&custommodule);
if (m == NULL) {
return NULL;
}
Py_INCREF(&CustomType);
if (PyModule_AddObject(m, "Custom", (PyObject *)&CustomType) < 0) {
Py_DECREF(&CustomType);
Py_DECREF(m);
return NULL;
}
return m;
}
这是一个简单的示例,展示了在自定义PyTypeObject中同时使用.tp_getattro / .tp_setattro和.tp_getset的基本思路和方法。你可以根据自己的实际需求进行相应的修改和扩展。
领取专属 10元无门槛券
手把手带您无忧上云