2012-08-14 143 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