Multiple Inheritance in Python C API

 ̄綄美尐妖づ 提交于 2020-01-23 02:42:27

问题


How do I create a type using the Python C API that inherits from multiple other types?

The Python documentation includes an example of a type that inherits from one other type, but there is no example or mention of multiple inheritance I could find.


回答1:


The C API does not support multiple inheritance. You'd have to call PyType_Type yourself, simulating a standard Python class statement. This is documented under the C API section on specifying a base type for an extension type:

PyTypeObject* PyTypeObject.tp_base

An optional pointer to a base type from which type properties are inherited. At this level, only single inheritance is supported; multiple inheritance require dynamically creating a type object by calling the metatype.

This field is not inherited by subtypes (obviously), but it defaults to &PyBaseObject_Type (which to Python programmers is known as the type object).




回答2:


Let's say you have a module named test, with the following classes:

class A:
    a = 1

class B:
    b = 2

And the idea is to create a new class C which inherits from A and B:

import test

class C(test.A, test.B):
    pass

The specification on PyTypeObject.tp_base says that it does not support multiple bases classes and that you have to create the class "by calling the metatype". In this case, the metatype is type, so the class can be created this way:

from test import A, B

C = type("C", (A, B), {})

Translating that to C is straightforward, although a bit verbose:

// from test import A, B
PyObject* test_module = PyImport_ImportModuleNoBlock("test");
if (test_module == NULL) return NULL;
PyObject* ClassA = PyObject_GetAttrString(test_module, "A");
if (ClassA == NULL) return NULL;
PyObject* ClassB = PyObject_GetAttrString(test_module, "B");
if (ClassB == NULL) return NULL;

// name, bases, classdict = "C", (A, B), {}
PyObject *name = PyUnicode_FromString("C");
if (name == NULL) return NULL;
PyObject *bases = PyTuple_Pack(2, ClassA, ClassB);
if (bases == NULL) return NULL;
PyObject *classdict = PyDict_New();
if (dict == NULL) return NULL;

// C = type(name, bases, classdict)
PyObject *ClassC = PyObject_CallObject(
    (PyObject*)&PyType_Type, PyTuple_Pack(3, name, bases, classdict));
if (ClassC == NULL) return NULL;
if (PyModule_AddObject(m, "C", ClassC)) return NULL;


来源:https://stackoverflow.com/questions/40593529/multiple-inheritance-in-python-c-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!