When running %%cython
-magic a lot happens under the hood. One can see parts of it when calling the magic in verbose mode, i.e. %%cython --verbose
:
- A file called
_cython_magic_b599dcf313706e8c6031a4a7058da2a2.pyx
is generated. b599dcf313706e8c6031a4a7058da2a2
is the sha1-hash of the %%cython
-cell, which is needed, for example, to be able to reload a %%cython
-cell (see this SO-post).
- This file is cythonized and built to a c-extension called
_cython_magic_b599dcf313706e8c6031a4a7058da2a2
.
- This extension gets imported - this is the moment your code prints 45, and everything from this module is added to the global namespace.
If you execute the cell again, none of the above happens. This is because the %%Cython
machinery can see that the cell has already executed and loaded - so nothing has to be done. The 3 steps above will be repeated if the cell is changed (because cell changes change the sha1-hash) or if the Python kernel running in Jupyter Lab (for example) is restarted.
To enforce that the steps above are performed, one has to pass --force
(or -f
) options to the %%cython
-magic-cell, i.e.:
%%cython --force
...
# 45 is printed
However, because compiling Cython code may be time consuming, one might prefer something like the example given below.
%%cython
def cfunc(int n):
cdef int a = 0
for i in range(n):
a += i
return a
def cython_main(int arg1):
# Print the output from calling the funtion
print(cfunc(arg1))
# And/or return the output
return(cfunc(arg1))
NOTE:
The cython_main()
function given above needs to be in the same cell with any def
, cdef
, or cpdef
functions that it calls, but is invoked from a separate cell to solve the print issue raised in the OP.
Here's an example invoking the cython_main()
function from a separate cell to pass a value of 10 to cfunc()
:
result = cython_main(10)
The result is:
45
This solves the print issue described in the OP because the call to cython_main()
from outside the %%Cython
cell forces cfunc() to be re-invoked even if the cell has been executed previously.