ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [코딩도장] day23. 클로저 사용하기
    IT/파이썬 2020. 9. 16. 00:29

    출처 : unsplash

    ■ 들어가기

    - 파이썬 코딩 도장 (남재윤/길벗). 을 공부하며 정리하는 블로그


    ▶ Unit33. 클로저 사용하기

         - 33.1 변수의 사용범위 알아보기

         - 33.2 함수 안에서 함수 만들기

         - 33.3 클로저 사용하기

     

    >> 33.1 변수의 사용범위 알아보기 <<

    소스 (global_variable.py) 결과
    x = 10  # 전역변수
    def foo() :
        print(x)    # 전역변수 출력

    foo()
    print(x)    # 전역변수 출력
    10
    10

    - 전역변수 : 스크립트 전체에서 접근할 수 있는 변수
    - 전역범위 : 전역변수에 접근할 수 있는 범위

     

    소스 (local_variable.py) 결과
    def foo() :
        x = 10      # foo의 지역변수
        print(x)    # foo의 지역변수 출력

    foo()
    print(x)        # 에러. foo의 지역변수 출력불가
    10
    Traceback (most recent call last):
      File "C:/project/local_variable.py", line 6, in <module>
        print(x)        # 에러. foo의 지역변수 출력불가
    NameError: name 'x' is not defined

    - 지역변수 : 변수를 만든 함수 안에서만 접근 가능하며, 함수 바깥에서는 접근 불가
    - 지역범위 : 지역변수에 접근할 수 있는 범위

     

    1. 함수 안에서 전역 변수 변경하기

    - 함수 밖에 선언된 변수와 동일한 이름의 변수를 함수 안에서 사용하더라도 이는 전역 변수가 아닌 지역 변수

    소스 (global_local_variable.py) 결과
    x = 10      # 전역 변수

    def foo() :
        x = 20  # x는 foo의 지역 변수
        print(x)    # foo의 지역 변수 출력

    foo()
    print(x)
    20
    10

    - 함수 안에서 전역 변수의 값을 변경하려면 global 키워드 사용!
    - 사용법 : global 전역변수

    소스 (function_global_keyword.py) 결과
    x = 10      # 전역 변수

    def foo() :
        global x    # 전역 변수 x를 사용하겠다고 설정
        x = 20
        print(x)

    foo()
    20
    20

    - 전역 변수가 없는 상태에서 global 키워드 사용 시 해당 변수가 전역 변수가 됨

    >>> y
    Traceback (most recent call last):
      File "<pyshell#8>", line 1, in <module>
        y
    NameError: name 'y' is not defined
    >>> def foo() :
    global y   # 변수 y는 미정의된 상태였으나 global 키워드로 전역변수 설정됨
    y = 20
    print(y)


    >>> foo(); print(y)
    20
    20

    [참고] 네임스페이스
    - 파이썬에서 변수는 네임스페이스(namespace)에 저장되며,
    - locals() 호출 시 현재 네임스페이스를 딕셔너리 형태로 출력 가능

    소스 (namespace.py) 결과
    def foo() :
        z = 10
        print('지역변수의 네임스페이스 확인')
        print(locals())
        print('--------------')

    foo()
    print('전역변수의 네임스페이스 확인')
    locals()
    print('--------------')
    지역변수의 네임스페이스 확인
    {'z': 10}
    --------------
    전역변수의 네임스페이스 확인
    --------------

    >> 33.2 함수 안에서 함수 만들기 <<

    - 기존 def로 함수를 만들었는데, 해당 함수 내에서 다시 def로 함수 생성하면 됨
    - 사용법
    def 함수이름1() :
        코드
        def 함수이름2() :
            코드

    소스 (function_in_function.py) 결과
    def print_hello() :
        hello = 'Hello, world!'
        def print_message() :
            print(hello)
        print_message()

    print_hello()
    Hello, world!

     

    1. 지역 변수의 범위

    - 함수이름1()의 지역변수는 함수이름2()를 포함한 그 안에 속한 모든 함수에서 접근 가능

    출처 : 파이썬 코딩 도장 (dojang.io)

     

    2. 지역 변수 변경하기

    - 함수 안의 함수에서 바깥쪽(함수이름1())에 있는 지역 변수의 값을 변경하려면 nonlocal 키워드 사용
    - 사용법 : nonlocal 지역변수

    소스 (function_nonlocal_keyword.py) 결과
    def A() :
        x = 10      # A의 지역 변수 x
        def B() :
            nonlocal x  # 현재 함수의 바깥쪽에 있는 지역 변수 사용
            x = 20      # A의 지역 변수 x에 20 할당

        B()
        print(x)        # A의 지역 변수 x 출력

    A()
    20

     

    3. nonlocal이 변수를 찾는 순서

    - nonlocal은 현재 함수의 바깥쪽에 있는 지역 변수 찾을 때 "가장 가까운 함수부터" 먼저 찾음

    소스 (function_in_function_nonlocal_keyword.py) 결과
    def A() :
        x = 10
        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

    - 함수 C() 에서 nonlocal x 시 가장 가까운 함수 B()의 x를 사용하게 됨 (x = 20
    - 함수 C() 에서 nonlocal y 시 가장 가까우 함수 A()의 y를 사용하게 됨 (y = 100)

     

    4. global로 전역 변수 사용하기

    - 함수 depth 상관없이 global 키워드 사용 시 무조건 전역 변수를 사용하게 됨

    소스 (function_in_function_global_keyword.py) 결과
    x = 1

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

    - 실제 코딩을 하다 보면 전역 변수로 선언한 내용은 코드가 길어짐에 따라 찾기가 어려워지므로
    - 전역 변수는 가급적 지양하고
    - 함수의 매개변수와 반환값을 이용해서 값을 처리하는 것이 좋음


    >> 33.3 클로저 사용하기 <<

    - 클로저?? 함수를 둘러싼 환경(지역변수, 코드 등)을 계속 유지하다가, 함수를 호출할 때 다시 꺼내서 사용하는 함수를 지칭
    - 프로그램의 흐름을 변수에 저장 가능
    - 즉, 클로저는 지역 변수와 코드를 묶어서 사용할 때 활용
    - 또한, 클로저에 속한 지역 변수는 바깥에서 직접 접근할 수 없으므로 데이터를 숨기고 싶을 때 활용

    소스 (closure.py) 결과
    def calc() :
        a = 3
        b = 5
        def mul_add(x) :
            return a * x + b    # 함수 바깥쪽에 있는 지역 변수 a, b를 사용해서 계산
        return mul_add          # mul_add 함수를 반환

    c = calc()
    print(c(1), c(2), c(3), c(4), c(5))
    8 11 14 17 20

    출처 : 파이썬 코딩 도장 (dojang.io)

    1. lambda로 클로저 만들기

    소스 (closure_lambda.py) 결과
    def calc() :
        a = 3
        b = 5
        return lambda x : a * x + b

    c = calc()
    print(c(1), c(2), c(3), c(4), c(5))
    8 11 14 17 20

     

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

    - 클로저의 지역 변수 변경 시 nonlocal 사용

    소스 (closure_nonlocal.py) 결과
    def calc() :
        a = 3
        b = 5
        total = 0
        def mul_add(x) :
            nonlocal total
            total = total + a * x + b
            print(total)
        return mul_add

    c = calc()
    c(1)
    c(2)
    c(3)
    8
    19
    33

     

    댓글

Designed by Tistory.