Python 09 Nested Function, Closure, Decorator

중첩함수(Nested Function)

1. 개념

  • 중첩함수(nested function) : 함수 안에 또 다른 함수가 선언되어 있는 것
  • 바깥 쪽 함수 : 부모함수, 외부함수 (위의 예시에서 parent_function())
  • 안 쪽 함수 : 내부함수(위의 예시에서 child_function())
  • 상위 부모함수 안에서만 호출 가능 => 부모함수를 벗어나서는 호출 불가
  • 중첩함수가 부모함수의 변수나 정보를 중첩함수 내에서 사용
  • 부모함수는 return 값으로 중첩함수 반환(=중첩함수의 return 값 반환)
  • 부모함수의 return 값으로 중첩함수가 선언되었기 때문에 부모함수의 변수, 즉 Enclosed function locals 영역의 변수는 외부에서 직접적으로 접근이 불가능. 그렇지만 중첩함수를 통해서 사용 가능
  • 위에서 6행 return값에 child_function() 괄호가 붙어있음
    함수 자체가 아닌 내부함수의 리턴값을 반환하는 함수는 nested function

2. 이해

위의 예시 변형

1

def parent_function():
    def child_function():
        return "this is a child function"


    return child_function 🔴


print(parent_function())
# <function parent_function.<locals>.child_function at 0x7feb10b2bee0>
  • 🔴 ()를 뺐더니 child_function 함수 객체의 주소가 리턴
  • 이렇게 내부함수의 리턴값을 반환하는 것이 아닌 내부함수 자체를 반환하는 것이 바로 클로저(closure)

2

def parent_function():
    def child_function():
        return "this is a child function"


    child_function() 🔴


print(parent_function())
# None
  • 🔴 return을 빼면 None 출력
    ∵ parent_function() 함수의 리턴값이 정의되어 있지 않기 때문

3

def parent_function():
    def child_function():
        print("this is a child function") 🔵


    child_function() 🔴


print(parent_function())
# this is a child function 🔵
# None 🔴
  • 🔵 중첩함수에 리턴 값은 없어도 print가 있기 때문에 부모함수안에서 실행된 child_function()에 의해서 print("this is a child function")가 실행되고
  • 🔴 부모함수의 리턴값은 없기 때문에 None이 출력

클로저(Closure)

1. 사용 이유

  • 어떠한 정보를 기반으로 연산을 실행하고 싶지만 기반이 되는 정보는 접근을 제한하여 노출이 되거나 수정이 되지 못하게 하고 싶을때 사용
  • 글로벌 변수를 쓰고 싶지 않을 때. 글로벌 변수는 함부로 사용하면 변경될 가능성이 있기 때문에 non-local 변수를 사용해서 글로벌 변수처럼 사용하는 것
  • 클래스를 사용하지 않고 싶을 때. 파이썬은 객체 지향언어이고 모든 데이터들은 클래스로 만들어져 있는데, 클래스는 함수보다 무겁기 때문에 비효율적일 수 있음

2. 개념

  • nested function과 다른 점은 위 예시에서처럼 부모함수의 리턴값이 내부함수의 값이 아닌 내부함수 자체를 반환
  • 사용 방법 : 클로져가 있을 때, 부모함수를 새로운 변수에 선언해주면 그 변수에는 내부함수의 주소값이 담기기 때문에 그 변수에 ()를 붙여서 함수로서 다시 호출해주는 것.

3. 이해

#클로저
  
def outer(num):
    def inner():
        return num + 3
    return inner
print(outer(10))
# <function outer.<locals>.inner at 0x01FDC340>

  

#cf)nested function
  
def outer(num):
    def inner():
        return num + 3
    return inner()
print(outer(10))
# 13

데코레이터(Decorator) ✍🏼

  • decorator는 closure처럼 중첩함수를 return 하는 함수
  • 다른 함수에 적용해서, 적용된 함수가 실행되기 전에 무조건 실행
  • '장식'이라는 사전적 의미 처럼 다른 함수 위에 장식처럼 달아놓은 함수
@is_paid_user
def jackpot_stock_information():
    return "계시가 내려졌습니다. 삼성전자를 사세요!"
  • decorator로 쓸 수 있는 함수 = nested function을 리턴하는 함수만 사용 가능

좋은 웹페이지 즐겨찾기