【问题标题】:Is there a way to inherit a PyTypeObject from a Python library into a custom type in CPython?有没有办法将 Python 库中的 PyTypeObject 继承到 CPython 中的自定义类型中?
【发布时间】:2021-03-11 18:15:43
【问题描述】:

我正在尝试在 CPython 中创建一个自定义类型,该类型继承自 Python 中已定义的类型对象。到目前为止,我的方法是使用PyImport_ImportModule,然后访问PyTypeObject 并将其设置为PyTypeObject 中的tp_base 属性。

进口:

PyTypeObject typeObj = {...} // Previously defined PyTypeObject for a fallback

int init() {
    PyObject* obj = PyImport_ImportModule("<absolute_path_to_python_module>");
    if (obj && PyObject_HasString(obj, "<python_type_object>")) {
        PyTypeObject* type_ptr = (PyTypeObject*) PyObject_GetAttrString(obj, "<python_type_object>");
        typeObj = *type_ptr;
    }
    if (PyType_Ready(&typeObj) < 0) return -1;
    ... // Other initialization stuff
}

继承:

PyTypeObject CustomType = {
    ... // Initialization stuff
    .tp_base = &typeObj;
};

自定义类型能够继承函数,但在isInstance(CustomType(), TypeObj) 上失败。当我尝试访问自定义类型的__bases__ 属性时,会引发分段错误。

【问题讨论】:

  • 非堆类型(大多数 C 类)并非旨在从堆类型(用 Python 编写的类型,加上一些奇怪的 C 类)继承。
  • 另外,typeObj = *type_ptr; 正在做一些完全不安全和不受支持的事情——你不能像那样复制 any Python 对象。
  • 所以我想在堆上分配内存,即使用malloc?

标签: python c inheritance cpython


【解决方案1】:

类型由身份标识,而不是价值。当您尝试执行typeObj = *type_ptr; 时,即使它“有效”,typeObj 的内存地址也与*type_ptr 不同,并且永远不会被视为同一类型。您需要保留身份。

将您的代码更改为:

PyTypeObject fallback_type_obj = {...} // Previously defined PyTypeObject for a fallback
PyTypeObject *type_ptr = NULL;

int init() {
    PyObject* obj = PyImport_ImportModule("<absolute_path_to_python_module>");
    if (obj && PyObject_HasString(obj, "<python_type_object>")) {
        type_ptr = (PyTypeObject*) PyObject_GetAttrString(obj, "<python_type_object>");
    }
    if (type_ptr == NULL) {
        if (PyType_Ready(&fallback_type_obj) < 0) return -1;
        type_ptr = &fallback_type_obj;
    }
    ... // Other initialization stuff
}

然后创建一个使用type_ptr 作为基础的堆类型(静态/全局类型将不起作用,因为type_ptr 没有被静态初始化为任何有用的东西)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-12
    • 2011-12-06
    • 2011-01-14
    • 1970-01-01
    • 2016-02-09
    • 1970-01-01
    • 2010-09-11
    • 2019-10-06
    相关资源
    最近更新 更多