我在cython中有一堆cdef
功能,这些功能由def
函数在pyx
文件中调用,例如:
cdef inline void myfunc_c(...):
(...)
return
def wrapper(...):
myfunc_c(...)
return
这效果很好。但是,要简化每个cdef
函数的python包装器,我试图通过将其分配给字典或类似的内容来按名称索引cdef
函数。
def wrapper(operation):
if operation == 'my_func':
func = myfunc_c
func(...)
return
但这不起作用。Cython抱怨它不知道myfunc_c
的类型。
有什么方法可以通过名称索引或调用cpdef
函数(例如使用字符串)?我也尝试了诸如locals()['myfunc_c']
之类的东西,但这也不起作用。
对于a 常规 cdef
函数这是不可能的 - 它们仅定义了c接口,但不定义python接口,因此没有内省。
对于用api
声明的cdef
函数(例如cdef api funcname()
)实际上是可能的。有一个无证件字典__pyx_capi__
。这定义了包含功能指针的Pycapsules的字典(用名称索引)。然后你会做
capsule_name = PyCapsule_GetName(obj)
func = PyCapsule_GetPointer(obj, capsule_name)
(其中 PyCapsule_*
是从python c api中函数的)。func
是void*
,您可以将其投入适当类型的功能指针。正确的类型很重要,并且取决于您!
尽管没有记录,但__pyx_capi__
接口相对稳定,Scipy用于其LowLevelCallable
功能。
cpdef
函数定义了python和c接口。在一个函数中,它们将在globals()
而不是locals()
中可用(因为locals()
仅给出该功能中定义的变量。)
我实际上并不认为您想这样做。我认为您只想使用cpdef
而不是cdef
,因为这会自动为该功能生成Python包装器。