【问题标题】:Cython Sharing Extension Types: classCython 共享扩展类型:类
【发布时间】:2018-10-17 00:43:43
【问题描述】:

我想在 Cython 中创建一个在 Python 中可读的类。目前,我的代码如下所示(当然它们并不完全相同,但代码的结构和组织是相同的)。

据我了解,我们不能直接从 Python 调用 Cython 对象,所以我打算让 TEST 类作为包装器工作,它可以调用更快的 Cython 类。
但是,我发现.pyx 中的类对象无法在同一个文件中调用 Cythonized 类中的cdef 函数,因此cdef class CYTEST 有另一个包装函数def func(),这对我来说看起来效率低下。 (我原来的问题中的这一段原来是错误的)

我发现我们可以在.pxd文件中声明对象(例如intlistobject),我们可以从.pyx文件中定义的Python类中读取Cython类中的对象(在下面的示例中,print(self.cytest.somenum))。

我们可以用 Cythonized 类做类似的事情吗?例子中,可以直接在TEST类中调用Cyfunc()吗?

main.py的一部分:

class MAIN:
    def __init__(self):
        cyobj1 = cyobj.CYTEST(self)
        cyobj2 = cyobj.CYTEST(self)
        cyobj1.func(3)

cyobj.pyx

cdef class CYTEST:
    cdef object main
    cdef int somenum

    def __cinit__(self, object main):
        self.main = main
        self.somenum = 5
    def func(self, int num):
        return self.Cyfunc(num)

    cdef void Cyfunc(self, int num):
        print(num)
        self.main.cyobj2.Cyfunc(num+1) # what I want to do

cyobj.pxd:

cdef class CYTEST:
    cdef public object main
    cdef public int somenum
    cdef public void Cyfunc(self, int num)  # this doesn't work

Official document 没有我的例子。

【问题讨论】:

  • 不确定您想要实现什么。您是否尝试在 python 中调用CYTEST(MAIN())?只有`cdef -functions/methods cannot be called from python - cdef class`是另一回事。
  • @ead 哦,它有效!那么,我们可以从另一个cdef class 调用cdef class 中的cdef 函数吗?在我的例子中,我想打电话给self.main.cyobj2.Cyfunc(num+1)

标签: python python-3.x cython


【解决方案1】:
self.main.cyobj2.Cyfunc(num+1) # what I want to do

问题在于它不知道self.main.cyobj2CYTEST,因此无法调用Cyfunc

最简单的选择是强制转换:

cdef CYTEST o = self.main.cyobj2
o.Cyfunc(num+1)

(如果转换失败,您将收到 TypeError)。

第二种选择是将Cyfunc 设为cpdef 函数,这样就可以在不知道类型的情况下以正常的Python 方式调用它。

第三种选择可能是将MAIN 也设为cdef class,然后指定cyobj1cyobj2 的类型,以及CYTEST.main。但是,这可能会导致循环依赖出现问题,所以我不完全确定这是可能的。

【讨论】:

  • 我尝试了最简单的方法,但我仍然收到AttributeError: 'cyobj.CYTEST' object has no attribute 'Cyfunc' 错误。
  • 第三种方法可行,但不是比调用cpdef函数慢吗?
  • 调用cpdef 函数会稍微慢一些。您的示例的修改版本适用于我,但我需要先修复很多小问题 - 您在此处显示的版本确实不是 minimal reproducible example。没有这个就很难知道你哪里出错了
  • 我忘了修改我的实际工作代码,您的评论清楚了这一点!谢谢。我忘了删除 .pyx 中的定义。
猜你喜欢
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-19
  • 2017-11-14
  • 1970-01-01
相关资源
最近更新 更多