Cython:通过引用传递
Cython: Pass by Reference
问题
我想通过引用 Cython 中的函数来传递向量。
cdef extern from "MyClass.h" namespace "MyClass":
void MyClass_doStuff "MyClass::doStuff"(vector[double]& input) except +
cdef class MyClass:
...
@staticmethod
def doStuff(vector[double]& input):
MyClass_doStuff(input)
问题
上面的代码在编译期间没有抛出错误,但它也不起作用。 input
在方法之后根本没有变化。
我也尝试了建议 in this question 但在这种情况下 cdef
函数将无法从 Python ("unknown member doStuff...").
访问
是否可以通过引用传递,如果可以,如何正确执行?
编辑
这不是 cython-c-passing-by-reference 的重复,因为我在上一节中提到了这个问题。提议的解决方案没有实现我的目标,即让 python 函数通过引用获取参数。
问题
正如 Kevin 和 jepio 在对您的问题的评论中所说,问题在于您如何处理 Python 中的向量。 Cython 确实定义了一个 cpp 向量 class,它会自动将边界处的列表 to/from 转换为 Cython 代码。
问题在于转换步骤:调用函数时:
def doStuff(vector[double]& input):
MyClass_doStuff(input)
转变为接近
的东西
def doStuff(list input):
vector[double] v= some_cython_function_to_make_a_vector_from_a_list(input)
MyClass_doStuff(input)
# nothing to copy the vector back into the list
答案
我想你有两个选择。第一个是完整地写出过程(即做两份手动副本):
def doStuff(list input):
cdef vector[double] v = input
MyClass_doStuff(v)
input[:] = v
这对于大向量来说会很慢,但对我有用(我的测试函数是 v.push_back(10.0)
):
>>> l=[1,2,3,4]
>>> doStuff(l)
>>> l
[1.0, 2.0, 3.0, 4.0, 10.0]
第二个选项是定义您自己的包装器 class,它直接包含一个 vector[double]
cdef class WrappedVector:
cdef vector[double] v
# note the absence of:
# automatically defined type conversions (e.g. from list)
# operators to change v (e.g. [])
# etc.
# you're going to have to write these yourself!
然后写
def doStuff(WrappedVector input):
MyClass_doStuff(input.v)
问题
我想通过引用 Cython 中的函数来传递向量。
cdef extern from "MyClass.h" namespace "MyClass":
void MyClass_doStuff "MyClass::doStuff"(vector[double]& input) except +
cdef class MyClass:
...
@staticmethod
def doStuff(vector[double]& input):
MyClass_doStuff(input)
问题
上面的代码在编译期间没有抛出错误,但它也不起作用。 input
在方法之后根本没有变化。
我也尝试了建议 in this question 但在这种情况下 cdef
函数将无法从 Python ("unknown member doStuff...").
是否可以通过引用传递,如果可以,如何正确执行?
编辑
这不是 cython-c-passing-by-reference 的重复,因为我在上一节中提到了这个问题。提议的解决方案没有实现我的目标,即让 python 函数通过引用获取参数。
问题
正如 Kevin 和 jepio 在对您的问题的评论中所说,问题在于您如何处理 Python 中的向量。 Cython 确实定义了一个 cpp 向量 class,它会自动将边界处的列表 to/from 转换为 Cython 代码。
问题在于转换步骤:调用函数时:
def doStuff(vector[double]& input):
MyClass_doStuff(input)
转变为接近
的东西def doStuff(list input):
vector[double] v= some_cython_function_to_make_a_vector_from_a_list(input)
MyClass_doStuff(input)
# nothing to copy the vector back into the list
答案
我想你有两个选择。第一个是完整地写出过程(即做两份手动副本):
def doStuff(list input):
cdef vector[double] v = input
MyClass_doStuff(v)
input[:] = v
这对于大向量来说会很慢,但对我有用(我的测试函数是 v.push_back(10.0)
):
>>> l=[1,2,3,4]
>>> doStuff(l)
>>> l
[1.0, 2.0, 3.0, 4.0, 10.0]
第二个选项是定义您自己的包装器 class,它直接包含一个 vector[double]
cdef class WrappedVector:
cdef vector[double] v
# note the absence of:
# automatically defined type conversions (e.g. from list)
# operators to change v (e.g. [])
# etc.
# you're going to have to write these yourself!
然后写
def doStuff(WrappedVector input):
MyClass_doStuff(input.v)