cython传值情况

cython pass by value situation

我遇到了一个关于 cython 按值传递的有趣案例。 代码写在jupyter notebook中:

%%cython -a
#cython: language_level = 3
#distutils: language = c++
from libcpp.map cimport map
from libcpp.string cimport string
cdef fun( map[ string, double ] a ):
    a[ b'H' ] = 10

cdef map[ string, double ] a
a[ b'H' ] = 0
fun( a )
print( a[ b'H' ] )

return值还是0

如果我们写成python:

def fun( a ):
   a[ 'a' ] = 10
a = { 'a' : 5 }
fun( a )
print( a[ 'a' ] )

答案将是 10

一些专家可以解释为什么 cython 和 python 表现出不同的行为吗?

如果你想在 C++ 中通过引用传递或在 Cython 中传递 C++ 对象,你应该通过引用传递它,即函数的签名 fun 应该是

cdef fun( map[ string, double ] &a ):
     ...

所有 Python 对象都是类型 PyObject * 和签名

的指针
def fun(object a):
   ...

大约翻译成

PyObject *fun(PyObject *a){
      ...
}

即参数作为指针传递,对应于纯 C 中的 C++ 引用。