Почему ноутбук Jupyter печатает результат Cython только один раз? - PullRequest
1 голос
/ 22 марта 2020

Я новичок в Cython (теперь использую его только для того, чтобы немного поработать). Я использую следующий код, чтобы увидеть общее представление об этом в блокноте jupyter.

%load_ext Cython
%%cython
def cfunc(int n):
    cdef int a = 0
    for i in range(n):
        a += i
    return a

print(cfunc(10))

Однако результат распечатывается только 45 раз. Когда я запускаю функцию печати, ячейка никого не показывает.

Есть ли проблемы с кодом? Как сделать так, чтобы ячейка печатала 45 так же, как обычный код python? Спасибо.

1 Ответ

1 голос
/ 22 марта 2020

При запуске %%cython -маги c многое происходит под капотом. Части этого можно увидеть при вызове волхвов c в подробном режиме, то есть %%cython --verbose:

  1. Создается файл с именем _cython_magic_b599dcf313706e8c6031a4a7058da2a2.pyx. b599dcf313706e8c6031a4a7058da2a2 - это sha1-ha sh %%cython -элемента, который необходим, например, для возможности перезагрузки %%cython -клетки (см. Этот SO-post ).
  2. Этот файл цитонизирован и построен с расширением c с именем _cython_magic_b599dcf313706e8c6031a4a7058da2a2.
  3. Это расширение импортируется - это момент, когда ваш код печатает 45, и все из этого модуля добавляется к глобальному пространству имен.

Когда вы снова запустите ячейку, ничего из вышеперечисленного не произойдет: с учетом ша-ха sh механизм может увидеть, что эта ячейка уже была выполнена и загружена - так ничего не поделаешь. Только когда содержимое ячейки изменяется и, следовательно, его ha sh, ca sh не будет использоваться, но 3 вышеупомянутых шага выполнены.

Чтобы обеспечить выполнение вышеуказанных шагов, нужно пройти --force (или -f) опций для %%cython -magi c -cell, то есть:

%%cython --force
...

# 45 is printed

Однако, так как расширение здания заново занимает довольно много времени, вероятно, предпочтет следующее

%%cython
def cfunc(int n):
  cdef int a = 0
  for i in range(n):
    a += i
  return a

# put the code of __main__ into a function
def cython_main():
   print(cfunc(10))

# execute the old main
cython_main()

и теперь вызывается cython_main() в новой ячейке, поэтому она переоценивается так же, как и обычный код python.

...