[Python] Decorator

Yerin·2019년 12월 6일
2

study-python

목록 보기
10/18

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
졸꾸 !!!

0개의 댓글