본문 바로가기

Python_programming/초중급편

python 범위 규칙, 할당, assignment, UnboundLocalError: local variable referenced before assignment

파이썬 namespace 를 공부하다 보면, 

unboundlocalerror 때문에 혼란이 오게 되는 경우가 있다.

이 포스팅은 그러한 사람들을 위한 포스팅이다. 

 

 

먼저, 파이썬 네임스페이스에 대한 기본적인 이미지는 아래와 같다. 

 

 

 

 

출처: https://www.programiz.com/python-programming/namespace

 

 

 

 

보통 파이썬에서 네임스페이스는 3가지가 있으며,

지역 네임스페이스, 전역 네임스이스, 빌트인 네임스페이스 가 있고, 위와 같은 관계이다. 

 

 

그리고 아래 코드같은 예제를 보면서 알게 된다.

 

 

 

# case1 

z = 100

def func_3(x,y):
    print(locals())
    a =  x + y + z 
    print("func_1 z", z, a)


func_3(100,100)

 

 

 

 

아하!

"전역 변수를 참조하여 지역 네임스페이스에 없을 경우, 전역 네임스페이스를 참조해서 처리하는구나!

 

그러다가, global 키워드에 대해서 공부 하다가 아래 코드를 접한다. 

 

 

 

# case2 

z = 100

def func_3(x,y):
    print(locals())
    z =  x + y + z 
    print("func_1 z", z, a)


func_3(100,100)

 

 

 

그리고 우리가 배운 사실에 대한 혼란이 온다...

지역 네임스페이스에 없으면 전역 네임스페이스에서 조회하던데 왜 에러가 뜨지? 

저 에러는 뭐지? 참조는 문제가 없는 것 같은데....?

 

여기서 중요한 것은 '할당'이다. 

전역 네임스페이스에서 참조할 때 '할당'은 조금 다르다... 

 

'다른 블로그들을 보다보면, global 을 쓰면 된다라고 하는데... 나와 같이 아니 case 1 에서는 global 안 써도 됐는데 왜 case 2 에서는 global 써야되는거야 ...ㅡㅡ...  아놔...'

 

 

처럼 의식으 흘러갈 수 있습니다. 

 

이제 이 부분에 대해 설명을 해보겠습니다.

사실, global 키워드에 대해서 이해하기 전에 징검다리가 하나 빠져있습니다. 여기서 알아야 하는 게 하나 더 있습니다. 

 

 

 

 

 

 

위 코드에서  x+= 1 부분에서 '할당'이 이루어지는데 여기서 기존 전역 변수 x 에  새로운 값을 할당하기 때문에 컴파일러는 이를 로컬 변수로 인식합니다. 따라서 foo  라는 함수 안에서(=지역 네임스페이스 안에서) 초기화되지 않은 로컬 변수(x) 를 할당하려고 하기때문에 오류가 발생합니다. 

 

 

 

 

 

 

 

이제 global 로 전역 변수를 선언함으로써 '할당'이 가능해집니다.

 

자, 정리하자면 global 선언 없이 지역 네임스페이스 공간의 로직을 짤 때, 모듈(=함수)에서 전역 네임스페이스의 변수를 '할당'할 일이 생기면 전역변수를 할당 시점에 컴파일러가 로컬변수로 간주하기 때문에 localbounderror 가 발생합니다. 

 

다른 블로그들을 보면 전역 변수를 지역 네임스페이스에서 '사용'할 때는 global 을 쓴다고 되어있는데 제 생각에는 '할당'이라고 표현해줘야 더 안 헷갈린다고 생각합니다. 왜그러냐면 case 1 에서처럼 값을 참조만 할 때는 global 선언 안해도 전역 변수 값의 레퍼런스에 잘 접근해서 연산이 이루어지기 때문입니다. 

 

 

이상 파이썬 범위 규칙인 localbound error 에 대해 살펴보았습니다. :)

 

 

 

 

 

 

--참고-- 

blog.weirdx.io/post/44564

 

Python - 파이썬 범위 규칙에 대한 잘못된 이해 - 이상한모임

본 글은 Toptal에 올라온 Buggy Python Code: The 10 Most Common Mistakes That Python Developers Make 글을 보고 공부하면서 쓴 글이다.

blog.weirdx.io

docs.python.org/2/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value

 

Programming FAQ — Python 2.7.18 documentation

Self is merely a conventional name for the first argument of a method. A method defined as meth(self, a, b, c) should be called as x.meth(a, b, c) for some instance x of the class in which the definition occurs; the called method will think it is called as

docs.python.org