2014-02-21 5 views
3

Я новичок в Cython и стараюсь ускорить мою мобильную игру kivy, используя код Cython в критическом AI-модуле. Мой код выглядит следующим образом:Ошибка компиляции Cython - указана локальная переменная до назначения

import numpy as np 
cimport numpy as np 

#not relevant parts 

cdef np.ndarray posarr 
cdef np.int poslast = 0 
cdef np.int posidx = 0 

def posarr_init(np.ndarray pawnpos, np.int act): 
    poslast = 0 
    # not relevant, but referencing poslast 

#not relevant, but including function where poslast is referenced (not assigned) 

def consider_pawn(np.int x, np.int y): 
    cdef np.int pact, posx, posy, resx, resy 
    cdef np.int p 
    cdef np.int found = 0 
    #not relevant 

    #in the code there is this line, posx and posy are local variables 
        posarr[poslast, posx, posy] = posarr[posidx, posx, posy] 

Здесь Cython дает мне эту ошибку во время компиляции:

Error compiling Cython file: 

------------------------------------------------------------ 
... 
       pact = 1 
     if pact == 1: 
      #pawn is active, create child position 
      for posx in range(11): 
       for posy in range(11): 
        posarr[poslast, posx, posy] = posarr[posidx, posx, posy] 
           ^
------------------------------------------------------------ 

position.pyx:98:34: local variable 'poslast' referenced before assignment 

Я могу видеть, что ошибки Cython компиляции представлены в том же порядке, в котором они появляются в коде. Мои вопросы:

Почему Cython рассматривает poslast локальную переменную?

Почему он не считал его локальной переменной в предыдущих функциях?

Сгенерированный C-файл пуст, он имеет только сообщение, что его нельзя использовать внутри. Есть ли способ заставить Cython оставить код C в файле, даже если есть ошибка компиляции? Может быть, глядя в этот файл поможет мне понять, сообщения об ошибках (например, почему эта переменная считается локальным) ...

ответ

3

Короткий ответ

Используйте global заявление явно объявить poslast как глобальные в каждой функции, пишет ему.

Длинный ответ

Cython следует Python правила связывания: если имя присваивается везде в функции, то предполагается, что локальная переменная, если явно не объявить его глобальным.

Я думаю, что вы выполняете и присваиваете poslast после вашего цикла цикла, что делает его неявно объявленной локальной переменной (типа object). Затем цикл использует этот, но неинициализированный локальный.

Ваши posarr_init функции аналогичным образом неверны. Он присваивает неявно объявленный локальный poslast, не затрагивая глобальный.

+1

+1. Cython также поддерживает ключевое слово nonlocal (Python 3) – jfs

Смежные вопросы