2012-08-14 145 views
0

我有以下Python代碼:UnboundLocalError嵌套函數的遞歸調用

​​

當我運行它,我得到以下錯誤:

Traceback (most recent call last): 
    File "ExtendPrefix.py", line 44, in <module> 
    print find_words("ABCDEFGH") 
    File "ExtendPrefix.py", line 41, in find_words 
    extend_prefix('', letters) 
    File "ExtendPrefix.py", line 38, in extend_prefix 
    result = extend_prefix(w + L, letters.replace(L, "", 1)) 
    File "ExtendPrefix.py", line 38, in extend_prefix 
    result = extend_prefix(w + L, letters.replace(L, "", 1)) 
    File "ExtendPrefix.py", line 35, in extend_prefix 
    if w in WORDS: results.add(w) 
UnboundLocalError: local variable 'results' referenced before assignment 

它顯然無法找到結果遞歸調用extend_prefix。爲什麼會這樣,我該如何解決它?

回答

2

由於您在嵌套函數內分配結果,Python假定您使用的是本地作用域變量,並在第35行拋出,即使它在更高範圍內是有效的名稱。如果您只是讀取變量而不寫入它,它通常會在較高的名稱空間對象上工作。但一旦出現賦值運算符,就跳轉到本地名稱空間。

Python scopes/namespaces

A special quirk of Python is that – if no global statement is in effect – assignments to names always go into the innermost scope. Assignments do not copy data — they just bind names to objects.

要解決這個問題,最簡單的是通過你想要使用到函數頭部的變量:

def extend_prefix(w, letters, results): 
     if w in WORDS: results.add(w) 
     if w not in PREFIXES: return 
     for L in letters: 
      extend_prefix(w + L, letters.replace(L, "", 1), results) 

而且你寫的函數的方式,你沒有返回一個集合,所以results = results | result將被炸燬,結果是None Type。

1

或者,如果您對結果使用默認值None並且然後將結果初始化爲空集,則不需要嵌套函數。它簡化了你的代碼並修復了你的問題。見下面...

def find_words(letters, pre = '', results = None): 
    if results is None: results = set() 
    if pre in WORDS: results.add(pre) 
    if pre in PREFIXES: 
     for L in letters: 
      find_words(letters.replace(L, '', 1), pre+L, results) 
    return results 

很高興在StackOverflow上看到另一個Udacity學生!

+1

我意識到我不應該因爲我正在走狗而設定結果。下一次,我應該在發佈問題之前遛狗! – 2012-08-14 00:50:11

+0

我以前做過很多次相同的事情。在電腦屏幕前幾小時後,我經常需要休息一下來處理我一直在學習的內容:) – 2012-08-14 00:55:07