2012-01-23 4 views
0
gCharlie = 0 
gJeff = 0 

def Bob(): 
    Charlie = gCharlie 
    Jeff = gJeff 
    Number = int(input("Hello and Welcome to Charlie's Number Guessing Game. Enter a nonnegative number from 0 to 10 not counting 0. ")) 

이 코드는 나에게 파이썬 3.2에서이 오류를 준다?파이썬 3.2.2 오류 지역 변수

+4

이 코드를 직접 실행했는데 오류가 발생하지 않았습니다. 이 함수를 호출하는 코드를 제공 할 수 있습니까? 그것은 별도의 파일에 있습니까? 그렇다면 어떻게 가져 오나요? –

+3

위의 두 가지 버전의 Python에서 위의 내용을 시도했지만 완벽하게 실행되었습니다. – senderle

답변

3

함수 범위 안에 새 로컬 변수로 만든 gJeff와 gCharlie를 다시 할당해야합니다. 파이썬에 전역 변수를 사용한다고 알리려면 함수의 맨 위를 다음과 같이 변경하십시오. 당신이 전역을 사용하는 Python을 말하지 않고

def Bob(): 
    global gCharlie 
    global gJeff 
    Charlie=gCharlie 

는, 그것이 말한대로, 함수에서 그 시점에서 할당되지 않은 지역 gCharlie 및 gJeff 변수를 참조하려고합니다. 사람들이 일하게하는 이유는 그들이 게시 한 코드 만 사용하기 때문입니다. 전역 변수를 참조하는 함수 내에서 값을 변경하지 않으면 명시 적으로 말하지 않고 전역 변수를 참조 할 수 있습니다.

원칙적으로 python은 변수 이름에 대해이 순서로 검색합니다. 로컬 범위, 내부에 중첩 된 모든 정의, 전역 내장 함수입니다. 왜냐하면 gJeff와 gCharlie는 함수의 지역 변수이기 때문입니다.

당신이 행동이보고 싶다면

때문에 함수 내에서이

x=5 

def useX(): 
    x=0  #this is a local variable 
    print "in function: ", x 

def main(): 
    print "in main(1): ", x 
    useX() 
    print "in main(2): ", x 

main() 

이 출력됩니다

in main(1): 5 
in function: 0 
in main(2): 5 

보고 시도, X는 새로운 지역 변수로 생성됩니다. useX 함수에 전역 x 문을 추가하면 마지막 줄이 "5"대신 "0"으로 인쇄됩니다.

+1

* "기본적으로 전역 변수를 인식하지 못합니다."*는 오해의 소지가 있습니다. 예를 들어, 모듈 수준에서'import some_module '을 통해 소개하는 모든 모듈 이름은 어떤 함수에서도 분명히 * 사용할 수있는 일반 전역입니다. 함수 내에서 바인딩을 변경하지 않으면'global'이 필요 없습니다 (예 : http://ideone.com/J2s6K). 필요하면 함수를 메소드로 리팩토링하고 전역을 인스턴스 속성으로 리팩터링해야합니다. – jfs

+0

더 명백한 예제는 함수 이름입니다. 'main()'안에서'useX()'를 호출하기 위해'global useX'를 사용할 필요가 없습니다. – jfs

+0

이 답변이 잘못되었습니다. –

2

기능 내에는 gCharlie =이있을 수 있습니다 (참고 : 첫 번째 글자는 g입니다). 대신 전역의

를 사용하여 매개 변수 :

def bob(charlie=0, jeff=0): 
    number = int(input("...")) 
    # ... 

bob(charlie=3) 
2

그것은 당신이 표시되지 않은 함수의 일부 gCharlie에 할당하고, 그래서 파이썬 컴파일러는 지역 변수로 표시 한 것을 의미한다 . 따라서 존재하기 전에 액세스하고 있습니다. 해결하려면 nonlocal 또는 global을 사용하십시오.

1

두 개의 이전 답변은 맞지만 두 가지 모두 약간 분명하지 않습니다. 나는 몇 가지 예제를 보여 드리겠습니다 :

당신이 보여 코드는 잘 작동합니다 :

>>> gCharlie = "Global!" 
>>> 
>>> def foo(): 
...  print(gCharlie) 
... 
>>> foo() 
Global! 
>>> print(gCharlie) 
Global! 

은 그래서 전혀 문제가되지 않습니다. 그러나 함수 내에서 전역 변수를 할당 할 수 없습니다 :

보시다시피
>>> gCharlie = "Global!" 
>>> def foo(): 
...  gCharlie = "Local!" 
...  print(gCharlie) 
... 
>>> foo() 
Local! 
>>> print(gCharlie) 
Global! 

, 전역 변수 gCharlie은 변경되지 않았다. 이것은 수정하지 않았기 때문에 같은 이름으로 새 로컬 변수를 만들었 기 때문입니다. 이것이 오류의 원인입니다.

>>> gCharlie = "Global!" 
>>> def foo(): 
...  oldCharlie = gCharlie 
...  gCharlie = "Local!" 
...  print(gCharlie) 
... 
>>> foo() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 2, in foo 
UnboundLocalError: local variable 'gCharlie' referenced before assignment 

힌트의 오류입니다.그것은 변수 gCharlie라고 말합니다. 문제는 글로벌 gCharlie에 액세스 할 수 없다는 것이 아니라 로컬 gCharlie가 아직 작성되지 않았 음을 의미합니다.

해결 방법은 로컬 변수를 만들지 않고 전역 변수를 수정하려는 것입니다. global 키워드를 사용하여이 작업을 수행합니다.

>>> gCharlie = "Global!" 
>>> def foo(): 
...  global gCharlie 
...  oldCharlie = gCharlie 
...  gCharlie = "Local!" 
...  print(gCharlie) 
... 
>>> foo() 
Local! 
>>> print(gCharlie) 
Local! 

지금 보셨 듯이 전역 변수가 수정되었습니다.

글로벌 변수는 일반적으로 나쁜 생각입니다. 그들을 피하십시오. 대신 매개 변수로 변수를 전달하십시오.