파이썬의 스코프와 이름 공간

Scopes and Namespaces

Namespaces

  • Namespaces은 서로 다른 순간에 만들어지고 서로 다른 수명을 갖는다.

  • Namespace의 예는

    • 내장 이름들의 집합 abs()

    • 모듈 전역 이름들

    • 함수 호출에서의 지역 이름들

    • 객체 어트리뷰트 집합

  • 서로 다른 Namespaces의 이름 간에 아무런 관계가 없다.

내장 이름들의 Namespaces

  • 내장 이름들의 Namespaces는 파이썬 인터프리터가 시작할 때 만들어지고, 영원히 지워지지 않는다.

  • builtins라는 모듈에 속하게된다.

모듈 전역 이름 Namespaces

  • 인터프리터가 끝날 때까지 남는다.

  • 인터프리터의 최상위 호출 때문에 실행되는, 스크립트 파일이나 대화형으로 읽히는 문장들은 __main__이라고 불리는 모듈 일부로 여겨져서 그들 자신의 Namespaces를 갖는다.

함수 지역 Namespaces

  • 함수가 호출될 때 만들어진다.

  • 함수가 복귀하거나 함수 내에서 처리되지 않는 예외를 일으킬 때 삭제된다.

Scope

  • Namespaces를 직접 액세스 할 수 있는 영역

  • 실행 중 어느 시점에서건, Namespaces를 직접 액세스 가능한, 적어도 3개의 중첩된 스코프가 있다.

    • 가장 먼저 검색되는, 가장 내부의 스코프는 지역 이름들을 포함합니다

    • 둘러싸고 있는 함수들의 스코프는, 가장 가까이서 둘러싸는 스코프로부터 검색이 시작됩니다, 비 지역(non-local) 이지만 비 전역(non-global) 이름들을 포함합니다

    • 마지막 직전의 스코프는 현재 모듈의 전역 이름들을 포함합니다

    • (가장 나중에 검색되는) 가장 외부의 스코프는 내장 이름들을 포함하고 있는 이름 공간입니다.

global과 nonlocal

  • 이름을 global로 선언하면, 모든 참조와 대입은 모듈의 전역 이름들을 포함하는 중간 스코프로 간다.

    • 특정 변수가 전역스코프에 있으며, 그곳에 재연결되어야 함을 가리킬 때 사용될 수 있다.

  • 가장 내부의 스코프 바깥에서 발견되는 변수들을 재연결하려면 nonlocal 키워드를 사용할 수 있다.

    • nonlocal로 선언되지 않으면, 그 변수들은 읽기 전용이다.

    • 특졍 변수가 둘러싸는 스코프에 있으며, 그곳에 재연결되어야 함을 가리킨다.

지역 스코프

  • 보통 지역스코프는 현재 함수의 지역이름들을 참조한다.

  • 함수 바깥에서, 지역 스코프는 전역 스코프와 같은 Namespaces를 참조한다.

모듈에서 정의된 함수의 전역 스코프는 어디에서 어떤 엘리어스를 통해 그 함수가 호출되는지에 관계없이, 그 모듈의 이름 공간이다.

  • 파이썬의 특별한 특징은 global문이 없을 때, 이름에 대입하면 항상 가장 내부의 스코프로 간다는 것이다.

  • 대입은 데이터를 복사하지 않는다. 이름을 단지 객체에 연결할 뿐이다.

  • 삭제도 마찬가지다. 지역스코프가 참조하는 이름 공간에서 연결을 제거한다.

def scope_test():
    def do_local():
        spam = "local spam" # do_local 함수 내부 스코프의 spam에 할
    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam" # 바로 바깥에 있는 spam을 재연
    def do_global():
        global spam
        spam = "global spam" # 완전 global의 spam에 재연결
        
    spam = "test spam"
    do_local()
    print("After local assignment:", spam)
    
    do_nonlocal()
    print("After nonlocal assignment:", spam)
    
    do_global()
    print("After local assignment:", spam)

scope_test()
print("In global scope:", spam)

# After local assignment: test spam
# After local assignment: nonlocal spam
# After local assignment: nonlocal spam
# After local assignment: global spam

Last updated