ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 클로저
    Python 2023. 10. 17. 16:22
    변수의 사용 범위 알아보기
    x = 10          # 전역 변수
    def foo():
        print(x)    # 전역 변수 출력
    
    foo()           # 함수 호출 
    10
    print(x)        # 전역 변수 출력
    10

    foo 함수에서 함수 바깥에 있는 변수 x의 값 출력, 함수 바깥에서도 x의 값 출력 가능

    함수를 포함해 스크립트 전체에서 접근할 수 있는 변수를 전역 변수라 하고, 전역 변수에 접근할 수 있는 범위를 전역 범위라고 함

     

    함수 안에서 전역 변수 변경

    def foo():
        x = 10      # 지역 변수
        print(x)    # 지역 변수 출력
    
    foo()           # 함수 호출 
    print(x)        # 에러, foo의 지역 변수는 출력할 수 없음
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'x' is not defined
    
    
    x = 10
    def foo():
        x = 20
        print(x)
    
    foo()
    20
    print(x)
    10
    
    
    x = 10        # 전역 변수
    def foo():
        global x    # 전역 변수 x를 사용하겠다 설정
        x = 20      # x는 전역 변수
        print(x)    # 전역 변수 출력
    
    foo()
    20
    print(x)        # 전역 변수 출력
    20
    
    
    # x = 10        # 전역 변수
    def foo():
        global x
        x = 20      # 지역 변수
        print(x)
    
    foo()
    20
    print(x)
    20

     

    네임스페이스

    변수는 네임스페이스(namespace, 이름공간)에 저장됨

    > locals 함수를 사용하면 현재 네임스페이스를 딕셔너리 형태로 출력

    >>> # 전역 범위에서 네임스페이스 출력
    >>> x = 10
    >>> locals()
    {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'foo': <function foo at 0x0000019720A4CC20>, 'x': 10}
    >>>
    >>>
    >>> # 함수 안에서 locals 사용
    >>> def foo():
    ...     x = 10
    ...     print(locals())
    ...
    >>> foo()
    {'x': 10}

     

    함수 안에서 함수 만들기
    def print_hello():
        hello = 'Hello, world!'
        def print_messeage():
            print(hello)
        print_messeage()
    
    print_hello()
    Hello, world!

    지역 변수 범위

    def A():
        x = 10    # A의 지역변수
        def B():
            x = 20
    
        B()
        print(x)
    
    A()
    10
    
    
    def A():
        x = 10    # A의 지역변수
        def B():
            x = 20
            print(x)
            
        B()
        print(x)    # 20 출력
    
    A()             # 10 출력

    지역 변수 변경

    nonlocal 지역변수

    def A():
        x = 10    # A의 지역변수
        def B():
            nonlocal x    # 현재 함수의 바깥쪽에 있는 지역 변수 사용
            # global x
            x = 20        # A의 지역 변수 x에 20 할당
    
        B()
        print(x)
    
    A()
    20
    
    # nonlocal이 변수 찾는 순서
    def A():
        x = 10    # A의 지역변수
        y = 100
        def B():
            x = 20
            def C():
                nonlocal x
                nonlocal y
                x = x + 30
                y = y + 300
                print(x)
                print(y)
            C()
        B()
        
    A()
    50
    400

     

    global로 전역 변수 사용

    함수가 몇 단계든 상관없이 global 키워드를 사용하면 무조건 전역 변수 사용

    x = 1
    def A():
        x = 10 
        def B():
            x = 20
            def C():
                global x
                x = x + 30
                print(x)
            C()
        B()
    A()
    31

     

    클로저 사용
    def clac():
        a = 3
        b = 5
        def mul_add(x):
            return a * x + b
        return mul_add
    
    c = clac()
    print(c(1), c(2), c(3), c(4), c(5))
    8 11 14 17 20

    함수를 둘러싼 환경(지역 변수, 코드 등)을 계속 유지하다가 함수를 호출할 때 다시 꺼내서 사용하는 함수를 클로저(closure)라고 함

    위에서는 c에 저장된 함수가 클로저

    클로저를 사용하면 프로그램의 흐름을 변수에 저장 > 지역 변수와 코드를 묶어서 사용하고 싶을 때 활용

    클로저에 속한 지역 변수는 바깥에서 직접 접근할 수 없으므로 데이터를 숨기고 싶을 때 활용

     

    람다로 클로저 만들기

    def clac():
        a = 3
        b = 5
        return lambda x: a * x + b
    
    c = clac()
    print(c(1), c(2), c(3), c(4), c(5))

    클로저의 지역 변수 변경하기

    def clac():
        a = 3    # 함수 calc의 지역 변수
        b = 5
        total = 0
        def mul_add(x):
            nonlocal total
            total = total + a * x + b
            print(total)
        return mul_add
    
    c = clac()
    c(1)
    8
    c(2)
    19
    c(3)
    33

     

    'Python' 카테고리의 다른 글

    클래스(2)  (0) 2023.10.18
    클래스(1)  (0) 2023.10.18
    람다  (0) 2023.10.17
    재귀호출  (0) 2023.10.17
    위치 인수와 키워드 인수 사용  (0) 2023.10.16
Designed by Tistory.