티스토리 뷰

Backend-dev/python

파이썬의 유효범위(scope)

RunningWater 2018. 4. 7. 02:17

유효범위는 무엇일까요?

유효범위(scope)는 변수의 수명을 뜻합니다. 더 쉽게 풀어서 얘기하자면 변수가 유효한 범위를 뜻합니다. 유효범위와 함께 알아야 하는 것이 전역변수와 지역변수입니다. 전역변수는 코드 전체에서 다 접근할 수 있는 변수를 뜻합니다. 지역 변수는 함수 내에서만 접근할 수 있는 변수라고 말할 수 있습니다.

파이썬의 유효범위는 어떻게 생성될까요?

파이썬의 유효범위(scope)는 함수를 통해서 생성됩니다.


a = 1
def scope():
    a = 2
    print(a)

scope()
print(a)


함수의 밖과 안에 각각 변수 a를 정의했습니다. 여기서 함수 밖의 a를 전역변수, 함수 내부의 a를 지역변수라고 합니다. scope 함수를 실행하면 2가 출력됩니다. 그렇다면 함수 밖에 있는 print(a)는 어떤 값을 출력할까요? 정답은 1입니다. scope 함수 밖의 print() 함수는 함수 내부로 들어가 값을 찾지 못합니다. 그래서 전역변수인 a에 접근해서 값을 출력한 것입니다. scope() 함수내에서 a = 2라고 정의한 것이 기존에 a = 1이라고 정의했던 것에서 값만 변경했다고 생각하시면 안 됩니다. 둘은 이름은 같지만 다른 a입니다.


이처럼 scope가 다르면 동일한 이름의 다른 변수를 생성할 수 있습니다.

한단계 더 나아가기

함수 내부의 a와 함수 외부의 a는 다른 변수라고 설명드렸습니다. 함수 외부에서는 함수 내부에서 값을 찾지 못하기 때문입니다. 그렇다면 반대는 어떻게 될까요?

a = 1
def scope():
    print(a)

scope()


함수 외부에서는 a가 정의되어 있지만, 함수 내부에서는 a가 정의되어 있지 않습니다. 그렇다면 scope는 에러를 일으킬까요? 이런 경우에는 함수내부에서 값(여기서는 a)을 찾지못하면 한 단계씩 더 위로 올라가면서(그 위가 전역이라면 전역에서 찾고, 다른 함수 내부에 있다면 자신을 포함하고 있는 함수에서 찾습니다.) 값을 계속 찾게 됩니다.


a = 1
def scope():
    def scope2():
        print(a)
    scope2()

scope()


scope() 함수 내부에 scope2() 함수가 있습니다. scope2()에는 print(a)를 실행하면 우선 자기의 유효범위를 확인해서 a를 발견할 수 없다면 scope() 함수에서 찾고, 거기서도 a를 발견할 수 없으면 전역 변수인 a의 값을 가져옵니다.

함수 내부에서 전역변수를 수정하기

함수 외부의 전역변수의 값을 찾기는 하지만 값을 변경해서 기존변수에 담을려고하면 에러가 납니다.

a = 1
def scope():
    a = a + 5
    
scope()
# UnboundLocalError: local variable 'a' referenced before assignment


그렇다면 함수내부에서 전역변수를 변경하려고 하면 어떻게 해야할까요? 이럴땐 전역변수를 가리킨다는 것을 알려주면 됩니다.


a = 1
def scope():
    global a
    a = a + 5
    print(a)

scope() #6
print(a) #6


global 변수명을 적어주면 해당 변수는 전역변수를 가리킨다는 것을 알려줍니다. 그래서 함수 내부에서 a의 값이 바뀌고 함수 외부에서 print(a)를 실행해도 6이 나오고, 함수 내부에서도 6이 나옵니다.

전역변수는 지양합시다.

코드 어디서도 접근할 수 있다면 자신도 모르게 수정될 수도 있고, 이런 수정이 에러를 일으킵니다. 전역변수는 되도록이면 지양하는 것이 좋습니다. 최소한의 전역변수만 사용할 수 있도록 고민하는 것이 좋습니다.

정적스코프와 동적스코프

마지막으로 정적스코프와 동적스코프를 알아보겠습니다. 선언된 시점에서 유효범위를 갖는 것이 정적스코프, 실행되는 시점에서 유효범위를 갖는 것이 동적스코프입니다. 헷갈리신다면 한번에 공부하지 마시고 조금 이해가 된 후 다시 포스팅을 보시는 것을 추천드립니다.


a = 1

def scope():
    a = 5
    scope2()

def scope2():
    print(a)

scope()


scope()함수를 통해서 실행된 scope2()함수는 5라는 값을 출력할까요 아니면 1이라는 값을 출력할까요? 파이썬은 정적스코프를 가집니다. 즉 실행될 때 a = 5이지만 자신이 선언될 때는 1이었기 때문에 1이라는 값을 출력합니다.



약간 난이도가 있는 주제였습니다. ^__^ 지금 이해가 되지 않더라도 너무 걱정하지 마세요. 차차 이해되실 겁니다.



공감은 제작자에게 큰 힘이 됩니다. 

'Backend-dev > python' 카테고리의 다른 글

클래스의 상속과 오버라이딩  (0) 2018.04.10
파이썬의 클래스(class)  (0) 2018.04.09
파이썬의 함수  (1) 2018.04.06
파이썬의 반복문(for, while)  (0) 2018.04.03
파이썬의 조건문(if)  (1) 2018.04.02
댓글