[Python] 함수(3): 변수의 범위와 네임스페이스

#7 네임스페이스와 변수의 범위

변수의 범위


동일한 이름의 변수가 여러번 사용할 때가 있다. 변수는 경우에 따라서 다른 객체를 참조할 수 있다. 이는 변수가 동일하더라도 참조하는 객체가 다를 수 있기 때문이다. 변수마다 변수의 범위가 있다. 변수의 범위를 알려면 네임스페이스를 이해해야한다.

변수와 네임스페이스


파이썬에서는 다른 언어와 달리 변수는 객체를 보관하는 장소가 아니라 객체에 붙인 이름이다. 변수 뿐만 아니라 함수, 클래스도 이름이다. 객체들을 식별하기 위해 이름들을 모은 공간네임스페이스(namespace)라고 한다.

하나의 네임스페이스에서는 이름은 중복되지 않는다. 즉, 하나의 네임스페이스에서 이름은 하나의 객체만을 가리킨다. 그렇지만 다른 네임스페이스에서는 같은 이름이 존재할 수 있다.

def func1():
    x = ["A"]
    print(x, id(x))

def func2():
    x = ["A"]
    print(x, id(x))

func1()
func2()

메인 프로그램은 전역 네임스페이스를 정의한다. 메인 프로그램의 네임스페이스에서 정의 된 변수는 전역변수다.

# 전역 네임스페이스
animal = "dog" # 전역변수

각 함수는 자신의 네임스페이스(Local namespace)를 정의한다. 전역 네임스페이스와 로컬 네임스페이스에서 동일한 이름이 존재하더라도 다른 객체다.

x = 1 # 전역변수

def func1():
    x = 10 # 지역변수
    print(x)

print(x) # 1
func1() # 10

다만, 함수가 전역변수를 사용하려면 `global` 키워드를 활용한다.

x = 10

def func1():
    global x  # 전역변수 x를 사용하겠다
    x = 12
    print(x)

print(x) # 10
func1() # 12
print(x)  # 12 : global 키워드 사용시 변수는 함수 내에서도 사용이 된다

LEGB 규칙

실제로는 동일한 이름의 변수를 많이 사용한다. 따라서 파이썬은 변수에 대응되는 객체를 찾기 위해 LEGB 규칙을 따른다. LEGB 규칙은 이름에 대응되는 객체를 찾는 순서이다.

  1. Local(지역)
  2. Enclosing(감싸는)
  3. Global(전역)
  4. Built-in(내장)

Local > Enclosing > Global > Built-in 순으로 이름에 대응되는 객체를 찾는다.

x = 1  # global scope

def outer_func():
    x = 10  # enclosing scope

    def inner_func():
        x = 100  # local scope

        print(x)  # 기준

    inner_func()

    print(x)

outer_func()

print(x)