2014-02-21 47 views
3

我是新來的Cython,並試圖通過在關鍵AI模塊中使用Cython代碼來加速我的kivy手機遊戲。我的代碼去如下: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

相關問題