Оператор cdef не разрешен здесь для структуры

У меня есть простой Astruct.pyx с определением структуры (Astruct.pxd):

cdef struct A:
    int x
    int y
    int z

И функция Cython, которая его использует (struct_test.pyx):

from random import randint
from Astruct cimport A

def do():
    N = 1000000
    M = 65535
    As = []
    total = 0
    for i in xrange(N):
        cdef A a
        a.x = randint(0, M)
        a.y = randint(0, M)
        a.z = randint(0, M)
        As.append(a)
    for i in xrange(N):
        total += As[i].x + As[i].y + As[i].z
    print total

Однако, когда я пытаюсь собрать struct_test.pyx, я получаю эту ошибку: «оператор cdef здесь не разрешен», указывая на «cdef A a». Он не жалуется на другое определение переменной A, если она находится вне цикла, но я не понимаю, что такого особенного в цикле for.


person Student4K    schedule 31.07.2014    source источник


Ответы (1)


Python и C имеют разные правила области видимости. Cython использует те же правила области видимости, что и Python, поэтому переменные, «объявленные» (назначенные первыми) внутри блока for/if/while или другого блока, находятся в области действия всей функции. Это также верно для переменных, объявленных с помощью cdef, но, как вы видели, эти переменные должны быть объявлены на уровне функции, а не в подблоке.

Я могу придумать как минимум две веские причины для этого требования:

  • Это более понятно: пользователи, приходящие в Cython с опытом работы на языке C, не будут удивлены, когда их переменные не будут иметь той области видимости, которую они могли бы ожидать.
  • Это означает, что код C, сгенерированный Cython, более точно соответствует исходному коду Cython, что, я уверен, упрощает отладку и реализацию для разработчиков Cython.
person Bi Rico    schedule 01.08.2014
comment
Дополнительные обсуждения и примеры см. здесь. - person mhsmith; 06.06.2020