Recieve global variable (Cython)

2019-09-22 03:27发布

问题:

I am using Cython in jupyter notebook.

As I know, Cython compiles def functions.

But when I want to call function with global variable it doesn't see it.

Are there any method to call function with variable?

one1 = 1
%%cython
cimport numpy as np
cdef nump(number1):
    return number1 + 1
nump(one1)

****This is sample code, to show moderators

回答1:

In an Ipython session I can do:

In [2]: %load_ext Cython
In [3]: one = 1
In [4]: %%cython
   ...: def foo(num):
   ...:    return num + 1
   ...: 
In [5]: foo(one)
Out[5]: 2

That is I define a cython function, but call it from Python with the global variable.

If I define the function with cdef I need to invoke it with a def function. fooc is not visible from Python.

In [9]: %%cython
   ...: cdef fooc(num):
   ...:    return num + 2
   ...: def foo_call(num):
   ...:    return fooc(num)
   ...: 
In [10]: foo_call(one)
Out[10]: 3

If I attempt to use one from within the cython file (magic cell) I get an error, the equivalent of a Python NameError

In [8]: %%cython
   ...: cdef fooc(num):
   ...:    return num + 2
   ...: print(fooc(one))
   ...: 

Error compiling Cython file:
...
/home/paul/.cache/ipython/cython/....: undeclared name not builtin: one

The ipython session variable one is not visible from within the magic cell.


Working from @DavidW's answer, this import works:

In [14]: %%cython
    ...: from __main__ import one
    ...: cdef fooc(num):
    ...:    return num + 2
    ...: print(fooc(one))
    ...: 
3

This fooc is not accessible from Python.

Note that the import uses the value of one at compile time.

In [22]: %%cython
    ...: from __main__ import one
    ...: cdef fooc(num):
    ...:    return num + 20
    ...: def fooc_call():
    ...:    print(fooc(one))
    ...: 
    ...: 
In [23]: fooc_call()
21
In [24]: one=343           # new value
In [25]: fooc_call()        # no change
21
In [26]: foo_call(one)     # uses the current value
Out[26]: 345


回答2:

Your code has a few errors, but I think the one you are asking about is one the line nump(one1) which gives the error

undeclared name not builtin: one1

This is because your %%cython snippets are essentially built in their own module. The %%cython magic in jupyter is more designed to create compiled functions that are accessible in your main code, rather than to access variables in your main code.

One solution is to add the line

from __main__ import *

at the start of your Cython block, to gain access to the "top level" scope. The answer @hpaulj has posted suggests the better approach where you define functions in Cython and use them outside the block.



标签: python cython