我想通过继承Cython中的python类来构建一个子类。看起来我不能直接这么做,因为我在下面得到了一个错误。有什么解决方法吗?
代码(osmium是一个第三方python包,可以使用pip安装):
import osmium
cdef class CounterHandler(osmium.SimpleHandler):
cdef list nodes, ways, relations
def __init__(self):
osmium.SimpleHandler.__init__(self)
self.nodes = []
self.ways = []
self.relations = []
def node(self, n):
pass
def way(self, w):
pass
def relation(self, r):
pass错误消息:
add.pyx:22:32: First base of 'CounterHandler' is not an extension type
Traceback (most recent call last):
File "setup.py", line 11, in <module>
ext_modules=cythonize("add.pyx"))
File "C:\ProgramData\Miniconda3\envs\osmium\lib\site-packages\Cython\Build\Dependencies.py", line 1102, in cythonize
cythonize_one(*args)
File "C:\ProgramData\Miniconda3\envs\osmium\lib\site-packages\Cython\Build\Dependencies.py", line 1225, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: add.pyx我尝试了DavidW提供的解决方案
解决方案2代码:
import osmium
cdef class CounterHandlerBase:
cdef list nodes, ways, relations
def __init__(self):
self.nodes = []
self.ways = []
self.relations = []
cdef node(self, n):
pass
cdef way(self, w):
pass
cdef relation(self, r):
pass
class CounterHandler(CounterHandlerBase, osmium.SimpleHandler): # osmium.SimpleHandler
def __init__(self):
CounterHandlerBase.__init__(self)
osmium.SimpleHandler.__init__(self)错误消息:
Traceback (most recent call last):
File "C:/Users/Administrator/Dropbox (ASU)/Work/CAVLite/OSM2GMNS/V2/cython_test/tets.py", line 7, in <module>
import solution2 as solution
File "solution2.pyx", line 28, in init solution2
class CounterHandler(CounterHandlerBase, osmium.SimpleHandler): # osmium.SimpleHandler
TypeError: multiple bases have instance lay-out conflict解决方案3代码:
import osmium
cdef class DummyBase:
def __init__(self):
pass
cdef class CounterHandler(DummyBase, osmium.SimpleHandler): # osmium.SimpleHandler
cdef list nodes, ways, relations
def __init__(self):
DummyBase.__init__(self)
osmium.SimpleHandler.__init__(self)
self.nodes = []
self.ways = []
self.relations = []
cdef node(self, n):
pass
cdef way(self, w):
pass
cdef relation(self, r):
pass错误消息:
Traceback (most recent call last):
File "C:/Users/Administrator/Dropbox (ASU)/Work/CAVLite/OSM2GMNS/V2/cython_test/tets.py", line 7, in <module>
import solution3 as solution
File "solution3.pyx", line 16, in init solution3
cdef class CounterHandler(DummyBase, osmium.SimpleHandler): # osmium.SimpleHandler
TypeError: best base 'osmium._osmium.SimpleHandler' must be equal to first base 'solution3.DummyBase'发布于 2021-05-21 00:28:31
这里有许多选项:
cdef class吗?你有真正的理由这样做(除了一个通用的,未经测试的信念,即"cdef classes更快“)?也许你可以使用一个普通的类来代替?您看起来没有使用任何不能用Python表示的属性(例如C指针)。请记住,Cython仍然编译常规类的def函数,因此可能不会像您想象的那样存在速度差异。cdef class的位和不需要为osmium.SimpleHandler的位(只有在与osmium.SimpleHandler的交互位于不需要的位中时才有效):cdef类CounterHandlerBase:#代码放在这里CounterHandler(CounterHandlerBase,osmium.SimpleHandler):#更多代码放在这里
cdef class (这实际上是内置在Python中的一个相当强的限制)。第二个基数/后续基数可以是常规类。因此,您可以创建一个“虚拟的”cdef基类来填充该角色:cdef类DummyBase:传递cdef类CounterHandler(DummyBase,osmium.SimpleHandler):#代码转到这里...
编辑:根据您报告的错误,看起来osmium.SimpleHandler已经是一个用C/C++编写的扩展类型。不幸的是,这意味着不可能在cdef class中继承它,因为Python中内置的对象布局的限制(将它定义为"external cdef class"可能行得通,但它看起来是从by pybind11生成的,这使得解决底层结构的工作相当困难)。
因此,选项2和3在这种情况下永远不会起作用。因为它已经是用C++写的,所以我怀疑用Cython语言重写东西会不会提高速度。
https://stackoverflow.com/questions/67611339
复制相似问题