Cython 子类化“第一个基础”...“不是扩展类型”,即使它是用 cdef 定义的

Pan*_*vid 3 python cython subclassing cythonize

我正在与 Cython 合作,为一个大学项目优化我的 Python 代码。为此,我想将 python 类转换为扩展类型。我目前在编译一种扩展类型时遇到问题,该扩展类型应该是另一种扩展类型的子类。这是我得到的错误:

src/core/ast/ast_classes/AstPreprocessor.pyx:9:27: First base of 'AstPreprocessor' is not an extension type
Run Code Online (Sandbox Code Playgroud)

AstPreprocessor的定义如下:

#Edit
from src.core.ast.ast_classes.AstBase import AstBase

cdef class AstPreprocessor(AstBase):
    cdef str function_name

    def __init__(self, function_ast, str function_name):
        super().__init__(function_ast)
        self.ast.index = self.ast.index.map(str)
        self.function_name = function_name
        self.symbol_list = super().get_symbol_list(self.function_name)

    #more method declarations     
Run Code Online (Sandbox Code Playgroud)

这是 AstBase 类的一部分,包括 中调用的方法AstPreprocessor#__init__()

cdef class AstBase:
    cdef int length
    def __init__(self, df):
        self.ast = df
        self.length = int(df.shape[0])
        self.childrens = {}

    #more method declarations    

    cdef get_symbol_list(self, str function_name):
        symbol_list = []
        for i in self.ast.index:
            i = int(i)
            if self.token(i).startswith('SYMBOL') \
                    and self.text(i) != function_name:
                symbol_list.append(i)
        return symbol_list
Run Code Online (Sandbox Code Playgroud)

这是我的 setup.py 中的 cythonize 命令:

ext_modules=cythonize(["src/core/ast/ast_classes/*.pyx",
                       "src/core/ast/preprocessing/*.pyx"], 
                       language_level=3, annotate=True),
Run Code Online (Sandbox Code Playgroud)

我查看了文档,但我很难真正理解为什么会出现此错误以及如何修复它。这是我第一次使用 Cython,因此我们将不胜感激。

编辑:我也尝试使用 cimport 但遗憾的是问题没有改变。

Dav*_*idW 5

你需要做两件事。首先为调用的.pxd 文件创建一个。这些行为有点像 C 标头,用于在不同模块之间共享 Cython 声明。它应该包含AstBaseAstBase.pxd

cdef class AstBase:
    cdef int length
    # any other cdef attributes

    cdef get_symbol_list(self, str function_name)
    # but not the implementation of get_symbol_list
Run Code Online (Sandbox Code Playgroud)

您的AstBase.pyx文件看起来基本相同:

cdef class AstBase:
    def __init__(self, df):
        self.ast = df
        self.length = int(df.shape[0])
        self.childrens = {}
Run Code Online (Sandbox Code Playgroud)

length请注意,自从它在 pxd 中声明以来,我已将其删除。请注意,所有属性都需要声明- 当前astchildrens不是。

那么AstPreprocessor.pyx你需要cimport而不是import AstBase

from AstBase cimport AstBase

# the rest stays the same
Run Code Online (Sandbox Code Playgroud)

cdef class这确保 Cython在编译时知道该类的详细信息(包括它是 a 的事实)。通常,如果 Cython 不知道对象的详细信息,它会假设它是在运行时可用的常规 Python 对象,这有时会导致令人困惑的错误消息。