首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过在Cython中继承python类来构建扩展类

通过在Cython中继承python类来构建扩展类
EN

Stack Overflow用户
提问于 2021-05-20 05:47:43
回答 1查看 87关注 0票数 0

我想通过继承Cython中的python类来构建一个子类。看起来我不能直接这么做,因为我在下面得到了一个错误。有什么解决方法吗?

代码(osmium是一个第三方python包,可以使用pip安装):

代码语言:javascript
复制
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

错误消息:

代码语言:javascript
复制
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代码:

代码语言:javascript
复制
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)

错误消息:

代码语言:javascript
复制
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代码:

代码语言:javascript
复制
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

错误消息:

代码语言:javascript
复制
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'
EN

回答 1

Stack Overflow用户

发布于 2021-05-21 00:28:31

这里有许多选项:

  1. 你真的需要它成为一个cdef class吗?你有真正的理由这样做(除了一个通用的,未经测试的信念,即"cdef classes更快“)?也许你可以使用一个普通的类来代替?您看起来没有使用任何不能用Python表示的属性(例如C指针)。请记住,Cython仍然编译常规类的def函数,因此可能不会像您想象的那样存在速度差异。

  1. 将其划分为需要为cdef class的位和不需要为osmium.SimpleHandler的位(只有在与osmium.SimpleHandler的交互位于不需要的位中时才有效):

cdef类CounterHandlerBase:#代码放在这里CounterHandler(CounterHandlerBase,osmium.SimpleHandler):#更多代码放在这里

  1. 的限制是第一个库必须是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语言重写东西会不会提高速度。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67611339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档