[Python] 네임스페이스(namespace)

cdwde·2021년 5월 15일
0
post-custom-banner

🎈 네임스페이스?

  • 특정한 객체를 이름에 따라 구분할 수 있는 범위

  • 이름들과 실제 객체들 사이의 매핑

  • 소속된 네임스페이스가 다르다면 같은 이름이 다른 개체를 가리키도록 하는 것 가능해짐


🎈 네임스페이스 분류

1. 전역 네임스페이스

모듈별로 존재하며 모듈 전체에서 통용될 수 있는 이름들이 소속됨

  • 전역 네임스페이스를 확인하는 globals 함수
a = 3
print(globals())

#출력결과
#{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0124AF40>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '<파일_경로>', '__cached__': None, 'a': 3}

2. 지역 네임스페이스

함수 및 메서드별로 존재하며 함수 내의 지역 변수들의 이름들이 소속됨

  • 함수는 전역과 별개의 네임스페이스를 가짐
a = 3

def func():
    a = 100
    b = 'python'
    def printer():
        print('hello')

func()
print(globals())	#a의 바뀐 값과 새로 할당한 변수, 함수 이름 보이지 않음

#출력 결과
#{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x01BEAF40>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '<파일_경로>', '__cached__': None, 'a': 3, 'func': <function func at 0x01BF8808>}
  • locals(): 실행하는 공간의 네임스페이스 출력
a = 3

def func(v):
    a = 100
    b = 'python'
    print('외부함수 namespace',locals())
    def inner_func():
        print('내부함수 namespace', locals())
    inner_func()

func('world')

#출력 결과
#외부함수 namespace {'v': 'world', 'a': 100, 'b': 'python'}
#내부함수 namespace {}
  • 네임스페이스가 다르면 값을 참조할 수 없음
    (❗ 함수는 globals 네임스페이스, 상위 함수의 변수 참조 가능)
a = 100

def func():
    f = 10
    def inner():
        b = 'python'
        print(f)
    inner()
    print(a)
    print(b)

func()

#출력 결과
#10
#100
#NameError: name 'b' is not defined

3. 빌트인 네임스페이스

  • 기본 내장 함수 및 기본 예외들의 이름이 소속됨

  • 파이썬으로 작성된 모든 코드 범위가 포함

  • 네임 스페이스 중 가장 최상위

  • 지역 네임 스페이스에 없고, 전역 네임 스페이스에도 없는 이름은 마지막으로 빌트인 네임 스페이스에서 검색

  • __builtins__


🎈 네임스페이스 특징

  • 네임스페이스는 딕셔너리 형태로 구현

  • 모든 이름 자체는 문자열로 되어있고 각각은 해당 네임스페이스의 범위에서 실제 객체를 가리킴

  • 이름과 실제 객체 사이의 매핑은 가변적이므로 런타임동안 새로운 이름이 추가될 수 있음 (But 빌트인 네임스페이스는 함부로 추가, 삭제할 수 없음)


🎈 외부 네임스페이스 변수 값 변경

  • global

    • 함수 내부에 선언한 global v 부분은 이름 v를 global에 선언한 v로만 사용하겠다는 뜻
    • v 변수의 값을 변경하면 global에 있는 변수가 참고하고 있는 객체가 바뀌게 됨
v = 'hello'
def func():
    global v
    v = 'HELLO'
    print(v)

func()
print(v)

#출력 결과
#HELLO
#HELLO
  • nonlocal
    외부함수에 있는 값을 변경
    가장 가까이서 둘러싸는 함수 영역에서 주어진 이름 찾음
def func():
    v = 10
    def inner():
        v += 5	#에러 발생 (내부함수에서 외부 함수의 지역변수 v 못찾고 있음)
        print(v)
    inner()

func()

#출력 결과
#UnboundLocalError: local variable 'v' referenced before assignment

def func():
    v = 10
    def inner():
        nonlocal v
        v += 5
        print(v)
    inner()

func()

#출력 결과
#15

def calc():
    a = 3
    b = 5
    total = 0
    def mul_add(x):
        nonlocal total
        total += a*x + b	#함수 calc의 지역변수 total에 누적
        print(total)
    return mul_add

c = calc()
c(1)
c(2)
c(3)

#출력 결과
#8
#19
#33

참고
https://wikidocs.net/23109
https://hcnoh.github.io/2019-01-30-python-namespace
https://injeblog.tistory.com/52
https://blog.naver.com/codeitofficial/221663950056
https://dojang.io/mod/page/view.php?id=2366
https://blog.hexabrain.net/347

post-custom-banner

0개의 댓글