2017-02-13 6 views
0

Я создал подтип из одного существующего типа Python с C API, следуя этим руководство Python C API Defining New TypesAPI Python C, Как вызвать метод базового типа из подтипа?

Я переопределен метод одного базового типа, зарегистрировав новый метод, благодаря tp_methods атрибута нового PyTypeObject. Это прекрасно работает.

Но, код должен также быть в состоянии выполнить метод базового типа (тот, который был перекрытым. Я не могу найти документацию о том, как это сделать.

Любой идея приветствуется, спасибо

ответ

1

Я думаю, что есть 2.5 варианты, в порядке сложности:

  1. Просто найти функцию C, которая определяет его при использовании C API шансов вы будете унаследованными от известного класса, который реализуется в С.. В этом случае вы выберете функцию C, используемую для метод и позвоните.

  2. Получить класс от объекта, основание из класса:

    а. PyObject* baseclass = self->ob_type->tp_base;

    b. Используйте C API эквивалент super():

    PyObject* baseclass = PyObject_CallFunctionObjArgs(&PySuper_Type,self->ob_type,self,NULL);

    С базой найден, то вы можете использовать C API эквивалент GetAttr, чтобы получить соответствующую функцию:

.

/* check baseclass against null */ 
PyObject* func = PyObject_GetAttrString(baseclass,"function_name"); 
/* check func is not null */ 
PyObject* result = PyObject_CallFunctionObjArgs(self,other_arguments..., NULL); /* adjust arguments here */ 
Py_DECREF(func); 
// decref result? 

Вы можете использовать другой способ его вызова, но вам нужно убедиться, что вы передаете себя с аргументами.


Вариант 2b, вероятно, наиболее гибким, поскольку он должен работать, когда несколько баз определяются через tp_bases.

+0

Благодаря DavidW, ваш ответ сделал 99% от работы. Я отправляю в следующем ответе свой код, так как мне пришлось внести некоторые небольшие исправления в ваш предлагаемый код. –

0

Я размещаю здесь свой рабочий код, в значительной степени вдохновленный ответом DavidW. Модификации:
1/экземпляр объекта подтипа Cast (self) для указателя PyObject для доступа ob_type. 2/Использовать func как первый параметр параметра PyObject_CallFunctionObjArg вместо self.

PyObject* baseclass = ((PyObject*)self)->ob_type->tp_base; 
if (baseclass == NULL) {...} 
PyObject* func = PyObject_GetAttrString(baseclass,"sum"); 
if (func == NULL) { ... } 
PyObject* result = PyObject_CallFunctionObjArgs(func,self, NULL); 
Py_DECREF(func); 
+0

Это хорошая практика в переполнении стека, чтобы добавить объяснение, почему ваше решение должно работать. Для получения дополнительной информации см. [How To Answer] (// stackoverflow.com/help/how-to-answer). –

Смежные вопросы