【发布时间】:2019-04-30 10:16:35
【问题描述】:
我正在编写一个 cython 模块,它提供了几种使用优化的cdef 函数的扩展类型。其中几个扩展类型(大约 10 个,每个包含大约 200 行代码)具有完全相同的结构,但不调用相同的 cdef 函数。我想分解我的模块,以便只有一种扩展类型可以处理我需要的所有不同配置。
为了更清楚地说明这一点,这是我正在编写的模块结构的一个(非常愚蠢的)示例:
cdef class A1:
cdef double x
def __init__(self, double x):
self.x = x
def apply(self):
self.x = f1(self.x)
cdef class A2:
cdef double x
def __init__(self, double x):
self.x = x
def apply(self):
self.x = f2(self.x)
cdef double f1(double x):
return x**1
cdef double f2(double x):
return x**2
...
以及我想获得的分解代码:
cdef class A:
cdef int n
cdef double x
def __init__(self, double x, int n):
self.x = x
self.f = globals()[f'f{n}']
def apply(self):
self.x = self.f(self.x)
在纯 Python 中,这种结构很容易使用 globals 或 getattr 设置,但在 cython 中,cdef 对象(当然)无法从 python 访问,因此在 globals() 中无法访问。
我猜这种代码的C 实现会使用函数指针,但我找不到如何在 cython 扩展类型中执行此操作。实际上真正的问题是'是否可以将指向 cdef 函数的指针添加为实例属性(在自身中)?如果没有,我怎样才能在不损失性能的情况下分解这种代码(即不改变我的 cdef 函数)?
【问题讨论】: