스코프를 쓰는 이유 2가지

스코프가 주는 장점은 크게 다음 2가지 이다.

  • 효율적인 메모리 관리
  • 예상치 못한 변수 수정을 방지

효율적인 메모리 관리

초코 공장으로 돌아왔다. 우리 공장의 청소를 담당하는 janitor sam 을 소개한다.

image-center

sam 은 공장을 지나다니며, 눈에 보이는 모든 것을 청소한다.

익살 맞게도 생겼다.

초코를 만드는 함수 안에서, 여러가지 재료, 여러가지 도구들을 사용한다고 하자.

def make_choco():
    bowl = '그릇'
    kakao = '카카오'
    fire = '불'
    # sam 이 나타납니다.

어떤 함수든, 그 끝에는 반드시 sam 이 나타나서 어질러진 모든 변수들을 ‘청소’ 한다. 함수 안에서 만들어진 지역변수들은 해당 함수가 종료되면, 활동 범위도 끝난다. 활동 범위를 벗어난 변수는 더 이상 필요가 없기 때문에 sam 이 청소하는 것이다.

여러분이 kakao = '카카오' 처럼 변수를 선언할 때 컴퓨터 내부에서는 메모리에 kakao 가 사용할 공간을 마련하고, 그 공간에 ‘카카오’ 를 저장한다.

그런데 더 이상 kakao 가 필요 없어진 상황에서도 그 공간을 정리하지 않는다면 컴퓨터 메모리는 한정되어 있기 때문에 언젠가 더 이상 새로운 변수를 위한 공간을 마련할 수 없게 될 것이다. 이는 곧바로 Python 프로그램의 종료로 이어진다. 치명적인 결함이다.

sam 이 여러분들을 대신해서 변수를 제거하고 다시 공간을 마련하기 때문에, 여러분이 작성한 파이썬 프로그램이 메모리가 바닥나는 일 없이 실행을 계속할 수 있다.

Garbage Collector

사실 Sam 의 진짜 이름은 Garbage Collector 라고 한다. 그리고 이는 Garbage Collector 는 Python 뿐 만 아니라 Java, C# 등 수 많은 다른 프로그래밍 언어에서도 존재한다. 프로그래머를 대신해서 메모리를 관리해 주는 역할을 한다.

예상치 못한 변수 수정을 방지

지금은 파이썬 프로그램이 위에서 아래로 순서대로 실행되지만 나중에 ‘비동기 프로그래밍’ 을 배우게 되면 프로그램의 어느 부분이 먼저 실행되고 언제 종료되는지를 예측할 수 없게 된다.

kim = '김 대통령'

def function_seoul():
    kim = '서울의 김씨'
    print(kim)

def function_incheon():
    kim = '인천의 김씨'
    print(kim)
    
def function_ulsan():
    print(kim) # 원래는 '김 대통령' 을 출력해야 합니다.
    
def function_gwangju():
    print(kim)
    
def function_busan():
    print(kim)
    

파이썬에서는 (기본적으로) 지역 스코프에서 전역변수를 수정할 수 없다고 했다. 만약에 이러한 제한이 없다고 생각해 보자. 그리고 각 함수들이 무작위 순서로 호출된다고 하자.

서울 -> 울산 -> 광주 -> 인천 -> 부산

순으로 호출된다고 하면 프로그램의 실행 중간에 ‘서울’ 과 ‘인천’이 kim 의 값을 바꿔버리고 만다!

원래는 ‘김대통령’ 을 출력해야 했던 수 많은 함수가 엉뚱하게도 ‘서울의 김씨’ 혹은 ‘인천의 김씨’ 를 출력하게 될 것이다.

이같이 많은 함수에서 같은 전역변수를 사용한다면 그 값이 중간에 홀연히 바뀌어도 복잡한 코드 속에서 이를 찾아내기는 매우 어렵다.

나중에는 “아니 왜 김 대통령이 아니라 다른 값이 나오지? 귀신 들렸나?” 라고 생각할지도 모른다.

관리하기 쉽고, 예측 가능한 프로그램을 만들기 위해서는 지역변수를 자주 사용하고 전역변수는 꼭 필요할 때(절대 수정할 일이 없는 변수등)에만 사용하도록 하는 것이 바람직하다.

id()

변수가 저장되는 메모리 위치를 쉽게 알 수 있는 방법이 있다. 지하철 각 객차에 번호가 매겨져 있는 것 처럼, 메모리 공간에도 12345 번째, 12346 번째… 처럼 번호가 매겨져 있는데 id() 를 사용하면 바로 해당 공간의 번호를 알려준다. 파이썬 인터프리터를 열어서 시험해보자.

>>> hi = 'abc'
>>> id(hi) # 1585694192 출력

출력 결과는 1585694192 이 아니라 다른 숫자일 것이다. 이는 컴퓨터 마다 메모리 크기가 다르고, 현재 쓰고있는 용량도 다 다르기 때문이다.

Updated:

Comments