2012-08-14 3 views
0

나는 다음과 같은 파이썬 코드가 있습니다UnboundLocalError 중첩 된 함수의 재귀 호출에

def find_words(letters): 
    results = set() 

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

    extend_prefix('', letters) 
    return results 

print find_words("ABCDEFGH") 

내가 그것을 실행하면, 나는 다음과 같은 오류 얻을 :

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

중첩 된 함수 내에서 결과를 할당하기 때문에 파이썬은 로컬 스코프 변수를 사용한다고 가정하고 더 높은 범위의 유효한 이름 임에도 불구하고 35 번째 줄을 던집니다. 변수를 읽고 쓰기 만하지 않았다면 상위 이름 공간 객체에서 자주 작동합니다. 그러나 할당 연산자가 나타나 자마자 로컬 네임 스페이스로 이동합니다. Python scopes/namespaces에서

: 당신은 또한

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) 

이 기능을 쓴 방법 :

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.

이 극복하려면, 가장 쉬운 방법은 함수 헤더에 사용하고자하는 변수를 전달하는 것입니다 세트를 반환하지 않으므로 results = results | result은 결과를 없음 유형으로 날려 버렸을 것입니다.

1

또는 결과에 기본값 없음을 사용하고 빈 세트로 초기화 된 결과를 포함하는 경우 중첩 된 함수가 필요하지 않습니다. 코드를 간소화하고 문제를 해결합니다. 그것은 StackOverflow의 다른 Udacity의 학생을 참조하는 것이 좋다 ... 아래

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 

하세요!

+1

내가 개를 산책 할 때 결과를 설정하지 않아도된다는 것을 깨달았습니다. 다음에 나는 질문을 게시하기 전에 개를 산책해야합니다! –

+0

나는 여러 번 전에 같은 일을 해왔다. 컴퓨터 화면 앞에 몇 시간 후 나는 종종 내가 배운 것을 처리하기 위해 휴식이 필요하다. :) –