Question

I am using many variables with the same type in all functions of the same module:

def func1(double x):
    cdef double a,b,c
    a = x
    b = x**2
    c = x**3
    return a+b+c

def func2(double x):
    cdef double a,b,c
    a = x+1
    b = (x+1)**2
    c = (x+1)**3
    return a+b+c

My question is, will it be the same if I did as shown below? with the variable declaration placed outside the functions? (The real case is different and has more than 2 functions)

cdef double a,b,c

def func1(double x):
    a = x+2
    b = (x+2)**2
    c = (x+2)**3
    return a+b+c

def func2(double x):
    a = x+2
    b = (x+2)**2
    c = (x+2)**3
    return a+b+c
Was it helpful?

Solution

In principle, cython handles global variables as python does, no matter whether it's a C or Python type. Have a look at this part of the FAQ.

So your (second) example would not work, you'd have to use global variable at the beginning of your function, like this:

def func2(double x):
    global a, b, c
    a = x + 2
    b = (x + 2) ** 2
    c = (x + 2) ** 3
    return a + b + c

However, at this point I would like to question, whether you really need to do this. Quite generally, there are good arguments, why global variables are bad. So you seriously might want to reconsider.

I assume, that your three doubles are just a toy example, so I'm not sure what your actual use case is. Judging from your (first) example, reusing code could be done instead by extending the function by another parameter, like so:

def func(double x, double y=0):
    cdef double a, b, c
    a = x + y
    b = (x + y) ** 2
    c = (x + y) ** 3
    return a + b + c

This would at least cover your examples func1 and func2 here by using y = 0 and y = 1 respectively.

OTHER TIPS

I made the following test and I believe it works to declare the variables shared by many functions outside, avoiding repeated code, without the need to specify with global.

In a _test.pyx file:

import numpy as np
cimport numpy as np
cdef np.ndarray a=np.ones(10, dtype=FLOAT)
cdef np.ndarray b=np.ones(10, dtype=FLOAT)
cdef double c=2.
cdef int d=5

def test1(double x):
    print type(a), type(b), type(c), type(d)
    print a + c*b + 1*c*x + d

def test2(double x):
    print type(a), type(b), type(c), type(d)
    print a + c*b + 2*c*x + d

In a test.py file:

import pyximport; pyximport.install()
import _test

_test.test1(10.)
_test.test2(10.)

gives:

<type 'numpy.ndarray'> <type 'numpy.ndarray'> <type 'float'> <type 'int'>
[ 28.  28.  28.  28.  28.  28.  28.  28.  28.  28.]
<type 'numpy.ndarray'> <type 'numpy.ndarray'> <type 'float'> <type 'int'>
[ 48.  48.  48.  48.  48.  48.  48.  48.  48.  48.]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top