我想通过继承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'
这里有许多选项:
你真的需要它成为
cdef class
吗?你有没有真正的原因(除了一个普遍的、未经测试的信念,即“cdef class
es更快”)之外?也许你可以用普通班代替?您看起来没有使用任何不能在Python中表示的属性(例如C指针)。请记住,Cython仍然编译常规类的def
函数,因此可能没有您想象的速度差异将其拆分为需要为
cdef class
的位和不需要的位(仅当与osmium.SimpleHandler
的交互在不需要的位中时,这才有效):限制是第一个基必须是
cdef class
(这实际上是Python内置的一个相当强的限制)。第二个/后续的基可以是常规类。因此,您可以创建一个“dummy”cdef
基类来填充该角色:编辑:根据您报告的错误,看起来
osmium.SimpleHandler
已经是用C/C++编写的扩展类型。不幸的是,这意味着它不可能在cdef class
中继承,因为Python中内置了对对象布局的限制(可能将其定义为"external cdef class"可以工作,但它看起来是从by pybind11生成的,这使得开发底层结构非常困难)因此,在这种情况下,选项2和3永远不会起作用。由于它是用C++编写的,我怀疑在Cython重写东西会加速一切。p>
相关问题 更多 >
编程相关推荐