전역변수를 test() 함수내에서 사용하고자 하는 경우, 아래와 같이 코딩하면 "UnboundLocalError: local variable 'cnt' referenced before assignment" 라는 에러가 발생한다. 뜻은 cnt 라는 변수에 값이 할당되기 전에 cnt 변수가 참조되었다는 의미이다.
def test():
if cnt == 200:
cnt+=100
print(cnt)
cnt = 200
test()
이유는 이렇다. 파이썬 인터프리터가 코드를 해석할때 test()함수 내부의 cnt+=100
문장, 즉 cnt 에 값이 할당된 문장을 보고 cnt 지역변수가 존재한다고 인식한다. 그리고 해석이 모두 끝난 후 소스코드를 실행할때 if cnt == 200
조건문을 보고, 지역변수가 생성되기 전에 if cnt == 200
조건문을 처리할 수 없다고 판단하여 에러를 발생시키는 것이다.
만약 cnt 변수에 값을 할당하지 않고, 단순히 비교만을 수행한다면 cnt 변수는 전역변수로 인식되고 정상작동 할것이다.
def test():
if cnt == 200:
print(cnt)
cnt = 200
test() # 200
정리하면, 함수 내에서 변수에 값을 할당하는 문장이 있으면 기본적으로 해당 변수는 지역변수로 인식된다. 만약 함수 내에서 전역변수에 값을 할당(변경)하고 싶은 경우, 해당 문장의 위쪽에 global 전역변수명
을 써주면 해당 변수는 지역변수가 아니라 전역변수로 인식된다.
def test():
global cnt
if cnt==200:
cnt+=100
cnt = 200
test()
print(cnt) # 300
리스트의 경우, 원소를 바꾸거나 append, pop 등을 할때는 global을 명시해주지 않아도 된다. 그러나 전역 리스트를 함수 내에서 대입연산자=
가 포함된 연산자를 사용해 변경시킬땐 global 전역리스트명
을 써줘야 한다.(=, +=, -= 등)
대입 연산자 사용하지 않을때
def test():
if len(arr) == 3:
arr.append("d")
arr = ["a","b","c"]
test()
print(arr) # ['a', 'b', 'c', 'd']
대입 연산자 사용할때, global 전역리스트명 필요
def test():
global arr
if len(arr) == 3:
arr = ["a", "b", "c", "d"]
arr = ["a","b","c"]
test()
print(arr) # ['a', 'b', 'c', 'd']
*그리고 당연하게 동일한 스코프 내에서 이름이 같은 전역 변수/리스트와 지역 변수/리스트는 동시에 사용될 수 없다.