在Python C API的多重继承

问题描述 投票:3回答:2

如何创建使用Python C API来自多个其它类型继承的类型?

Python文档包括从一个其他类型的继承类型的例子,但没有例子或多重继承的提及,我能找到。

python c python-2.7 multiple-inheritance python-c-api
2个回答
1
投票

在C API不支持多重继承。你不得不打电话PyType_Type自己,模拟标准的Python class声明。这是在上specifying a base type for an extension type的C API节记载:

PyTypeObject * PyTypeObject.tp_base

一个可选的指针,从该类型的属性继承的基类型。在这个层面上,只有单继承支持;多重继承需要动态通过调用元类型创建一个类型的对象。

该字段不是由亚型(明显)继承的,但它默认&PyBaseObject_Type(其中Python程序员被称为类型object)。


0
投票

比方说,你有一个模块名为test,具有以下类:

class A:
    a = 1

class B:
    b = 2

而这个想法是创建一个新类CAB继承:

import test

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

specification on PyTypeObject.tp_base说,它不支持多个基础类和你“通过调用元类型”创建类。在这种情况下,使用元是type,所以类可以创建这样:

from test import A, B

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

翻译,为C是简单的,虽然有点冗长:

// 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;
© www.soinside.com 2019 - 2024. All rights reserved.