如何调用cython cdef()函数,该函数包含python中的函数作为参数? [英] How to call a cython cdef() function that contains as a parameter a function in python?

查看:329
本文介绍了如何调用cython cdef()函数,该函数包含python中的函数作为参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个cdef函数,该函数的参数中有一个函数。我正在尝试生成将调用它的python包装器函数。我知道将函数定义为cpdef()即可访问该函数的python版本。但是,如果这样做,我将得到一个错误(如预期的那样),该错误表示python无法识别我提供的函数定义。

I have a cdef function that has amongst its parameters a function. I am trying to generate a python 'wrapper' function that will call it. I know that defining a function as cpdef() I would be able to get access to a python version of the function. However, if I do this, I will get an error (as expected) that says that python cannot recognize the function definition I provided.

有什么建议吗?

我的原始函数是特定于域的,而且很长,但是我认为下面的示例可以捕获我追求的是什么。我将定义以下 cdef()函数,

My original function is domain specific and quite long but I think that the following example captures what I am after. I would have the following cdef() function defined,

ctypedef double (*ftype) (double)

cdef cy_myfunc(int a,..., double x, ftype f):
  ...
  cdef double result
  result = f(x)

  return result

定义以下内容,以便我可以在python中调用它:

and I would like to define something like the following so that I can call it in python:

def py_myfunc(a,..., x, f):
    return cy_myfunc(a,...,x,f)


推荐答案

如果您确实需要这样做(可以考虑进行重构,这样就不用了)-您需要某种 PyObject 来存储c函数指针。

If you actually need to this (might think about refactoring so you don't) - you need some kind of PyObject to store the c function pointer.

PyCapsule api提供了一种在python空间中传递不透明指针的方法。可以这样做,我可能缺少一些安全检查

The PyCapsule api provides a way of passing opaque pointers around in python space. Could do something like this, I'm probably missing some safety checks

%%cython
from cpython.pycapsule cimport PyCapsule_New, PyCapsule_GetPointer

ctypedef double (*ftype) (double)

# c function you want to wrapper
cdef double f(double a):
    return a + 22.0

# wrapper capsule
wrapped_f = PyCapsule_New(<void*>f, 'f', NULL)

cdef cy_myfunc(double x, ftype f):
  cdef double result = f(x)
  return result

def py_myfunc(double x, object f_capsule):
    cdef ftype f = <ftype> PyCapsule_GetPointer(f_capsule, 'f')
    return cy_myfunc(x, f)

用法

wrapped_f
# Out[90]: <capsule object "f" at 0x0000000015ACFE70>

py_myfunc(2, wrapped_f)
# Out[91]: 24.0

这篇关于如何调用cython cdef()函数,该函数包含python中的函数作为参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆