[Python] Decorator

Yerin·2019년 12월 6일
2

study-python

목록 보기
10/18
post-custom-banner

Dectorator 란?

한마디로 말하자면, 함수에 장식을 붙이듯 앞뒤로 원하는 코드를 추가하는 기법이다.

  1. 다른 function의 기능을 조작하여 새로운 function을 만드는 것.
  2. 코드를 더욱 간결하게 만들며, 더욱 pythonic한 코드를 만들 수 있다.
  3. 코드 refactoring - 코드의 중복을 줄여준다.
  4. 어떤 함수를 받아 명령을 추가한뒤 이를 다시 함수의 형태로 반환하는 함수.
  5. 어떤 함수의 내부를 수정하지 않고 기능에 변화를 주고싶을 때 사용한다.

기본 구조

def decorator_name(func):
	def inner_func_name(*args, **kwargs):
    	기존 함수에 추가할 명령
        return func(*args, **kwargs)
    return inner_func_name

클로저와 비슷하게 생겼지만, 차이점은 "다른 함수를 인자로 받는다"는 점.

예시)

def inner():
	print("결과를 출력합니다.")
    
def outer(func):
	def wrapper():
    	print("-"*20)
        func()
        print("-"*20)
    return wrapper
    
inner = outer(inner)
inner()

outer가 직접 박스를 그리지 않고 지역함수 wrapper에게 이 작업을 시킨다. wrapper 지역함수가 인수로 전달받은 함수를 대리호출하며 outer는 wrapper함수를 만들어 리턴한다. 이때 리턴하는 지역함수를 inner함수가 다시 대입받는데 이 구문에서 좌우변의 inner는 다른 함수이다.

inner = outer(inner)

여기서 좌변은 원래의 함수 앞뒤에 박스를 그리는 wrapper 함수
우변은 결과를 출력하는 원래의 inner 함수

다시 말하자면, outer로 전달되는 inner는 결과만 출력하는 함수이며, 이 함수는 wrapper지역 함수의 클로저에 기억된다. outer가 리턴하는 지역함수 wrapper를 대입받는 inner는새로 생성한 지역함수에 대한 별명이다. 이제 inner를 호출할때 outer 거칠 필요없이 inner()라고 호출하면 된다.

inner = outer(inner)구문으로 함수를 포장하여 재정의하는 것을 간편하게 표기한 것이 @outer 데코레이터이다. 이 구문은 inner가 outer에 의해 래핑됨을 바로 알 수 있어 직관적이고 함수정의문과 데코레이터가 붙어있어 가독성이 좋다.

def outer(func):
	def wrapper():
    	print("-" *20)
        func()
        print("-"*20)
    return wrapper
    
@outer
def inner():
	print("결과를 출력합니다. ")
  
inner()

데코레이터는 기존 코드는 그대로 두고 추가적인 처리를 쉽게 할 수 있다는 면에서 편리하다. 한번만 잘 작성해두면 일련의 함수에 공통적으로 적용할 코드를 손쉽게 적용할 수 있고 유지 보수도 쉽다. 함수 실행 전에 특정한 조건을 점검한다거나 로그를 남길 수도 있다.

ref: <파이썬 정복> -김상형 지음

profile
졸꾸 !!!
post-custom-banner

0개의 댓글