Jestem nowy w Cython (używaj go tylko do robienia małego HW). Używam następującego kodu, aby zobaczyć ogólną ideę w Notebooku Jupsytera.

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

print(cfunc(10))

Jednak drukuje tylko wynik 45 raz. Po uruchomieniu funkcji drukowania komórka nie pokazuje nikogo 45.

Czy są jakieś problemy z kodem? Jak mogę sprawić, że komórka wydrukuje 45 tylko tak samo jak normalny kod Pythona? Dzięki.

1
Tony Lucas 22 marzec 2020, 20:08

1 odpowiedź

Najlepsza odpowiedź

Podczas jazdy %%cython - Magia wiele dzieje się pod maską. Można zobaczyć jego części podczas dzwonienia do magii w trybie Verbose, tj. %%cython --verbose:

  1. Generowany jest plik o nazwie _cython_magic_b599dcf313706e8c6031a4a7058da2a2.pyx. b599dcf313706e8c6031a4a7058da2a2 jest Sha1-Hash %%cython, który jest potrzebny na przykład, aby móc przeładować %%cython - komórka (patrz ta So-post ).
  2. Ten plik jest cythonizowany i zbudowany do rozszerzenia C o nazwie _cython_magic_b599dcf313706e8c6031a4a7058da2a2.
  3. To rozszerzenie jest importowane - jest to moment, w którym Twój kod drukuje 45, a wszystko z tego modułu jest dodawane do globalnej przestrzeni nazw.

Po ponownym wykonaniu komórki nic o powyższych nie dzieje się: Biorąc pod uwagę Sha-Hash Maszyny widzi, że komórka została już wykonana i załadowana - nic do zrobienia. Tylko wtedy, gdy zawartość komórki zostanie zmieniona, a zatem jego hash nie zostanie użyty, ale wykonane powyżej 3 kroki.

Aby egzekwować, że powyższe kroki są wykonywane, należy przejść --force (lub -f) Opcje do %%cython - Magic-Cell, I.e.:

%%cython --force
...

# 45 is printed

Jednakże, ponieważ na nowo przedłużenie budynku jest całkiem czasochłonne, prawdopodobnie preferowałoby następujące

%%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()

I teraz dzwoniąc cython_main() w nowej komórce, więc zostanie ponownie przetoczony tak samo, jak zwykły kod Pythona.

2
ead 22 marzec 2020, 20:04