【问题标题】:Cython: Pass by ReferenceCython:通过引用传递
【发布时间】:2015-06-04 01:41:03
【问题描述】:

问题

我想通过引用 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 访问(“未知成员 doStuff...”)。

是否可以通过引用传递,如果可以,如何正确执行?

编辑

这不是cython-c-passing-by-reference 的重复,因为我提到了上面部分中的问题。建议的解决方案没有实现我的目标,即让 python 函数通过引用获取参数。

【问题讨论】:

  • 你打算如何在 Python 中构建一个vector<double>?因为这是您唯一可以使用...调用该函数的方法
  • 你希望如何从 python 代码中传入一个向量?
  • Cython 定义了一个 cpp 向量类来使用。在 python 级别上,列表可以正常工作。详情请见vector.pxd

标签: python c++ pass-by-reference cython


【解决方案1】:

问题

正如 Kevin 和 jepio 在 cmets 中对您的问题所说的那样,问题在于您如何在 Python 中处理向量。 Cython 确实定义了一个 cpp 向量类,它会自动转换为/从边界处的列表转换为 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]

第二种选择是定义自己的包装类,直接包含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)

【讨论】:

    猜你喜欢
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-12
    • 2013-09-10
    • 2020-04-01
    • 1970-01-01
    • 2011-06-28
    相关资源
    最近更新 更多