I have met an interesting case regarding cython pass by value. The code is written in 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' ] )
The return value is still 0
If we write it in python:
def fun( a ):
a[ 'a' ] = 10
a = { 'a' : 5 }
fun( a )
print( a[ 'a' ] )
The answer will be 10
Can some experts explain why cython and python show different behavior?
If you want to pass by reference in C++ or a C++-objects in Cython you should pass it by reference, i.e. the signature of the function fun
should be
cdef fun( map[ string, double ] &a ):
...
All Python-objects are pointers of type PyObject *
and signature
def fun(object a):
...
is approximately translated to
PyObject *fun(PyObject *a){
...
}
i.e. arguments are passed as pointers, which corresponds to C++'s-references in pure C.