我正在与Cython合作,为一个大学项目优化我的Python代码。为此,我想将python类转换为扩展类型。我目前在编译一种扩展类型时遇到问题,应该是另一个扩展类型的子类。这是我得到的错误:
src/core/ast/ast_classes/AstPreprocessor.pyx:9:27: First base of 'AstPreprocessor' is not an extension type
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
以下是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
这是我的setup.py:中的cythosize命令
ext_modules=cythonize(["src/core/ast/ast_classes/*.pyx",
"src/core/ast/preprocessing/*.pyx"],
language_level=3, annotate=True),
我已经查看了文档,但我很难真正理解为什么会出现这个错误以及如何修复它。这是我第一次使用Cython,因此任何帮助都将不胜感激。
编辑:我也尝试过使用cimport,但遗憾的是问题没有改变。
您需要做两件事。首先为AstBase
创建一个名为AstBase.pxd
的.pxd文件。这些行为有点像C头,用于在不同模块之间共享Cython声明。它应该包含
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
您的AstBase.pyx
文件看起来基本相同:
cdef class AstBase:
def __init__(self, df):
self.ast = df
self.length = int(df.shape[0])
self.childrens = {}
注意,自从length
在pxd中声明以来,我已经删除了它。请注意,所有属性都需要声明——目前ast
和childrens
没有。
然后在AstPreprocessor.pyx
中,您需要cimport
而不是import
AstBase
from AstBase cimport AstBase
# the rest stays the same
这确保Cython在编译时知道类的详细信息(包括它是cdef class
的事实(。通常,如果Cython不知道对象的详细信息,它会假设它是一个在运行时可用的常规Python对象,这有时会导致令人困惑的错误消息。