为什么Jupyter Notebook会"忘记"Cython从一个单元格到另一个单元格?

Nem*_* L. 2 cython jupyter-notebook

当我使用cython编译一个单元格时,似乎Jupyter忘记了下一个单元格中编译的函数.这在我看来是不对的.出了什么问题?

我正在使用笔记本的5.0.0版本

Python 3.6.1 |Anaconda custom (x86_64)| (default, May 11 2017, 13:04:09) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]
Run Code Online (Sandbox Code Playgroud)

这是一个产生问题的MWE:

单元格1:

%load_ext Cython
Run Code Online (Sandbox Code Playgroud)

单元格2:

%%cython
cdef int foo():
    return 3

print(foo())
Run Code Online (Sandbox Code Playgroud)

这会产生:

3
Run Code Online (Sandbox Code Playgroud)

在下一个单元格中,我有

print(foo())
Run Code Online (Sandbox Code Playgroud)

这会产生:

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-3-9701608cebc0> in <module>()
----> 1 print(foo())

NameError: name 'foo' is not defined
Run Code Online (Sandbox Code Playgroud)

mgc*_*mgc 6

我想这是因为你没有foo在python(with cpdef)中定义你的函数,只是只给它一个C签名(with cdef)所以它只能从cython代码中调用.
在单元格2中你可以调用它,因为你仍在使用cython代码,但在你的单元格3中你回到了纯python并且该函数不可用.有各种方法从foopython函数中获取结果:

%%cython
# Not reachable in pure python:
cdef int foo():
    return 3

# Python visible function signature:
cpdef int foo2():
    return 3

# Or a wrapper around the cython function:
def foo3():
    return foo()
Run Code Online (Sandbox Code Playgroud)

您现在可以尝试调用foo2()foo3()在您的python代码中.

如果您没有看到,请参阅文档的相关部分之一.