데커레이터(Decorator)
사전 개념
데커레이터를 이해하기 위해서는 아래와 같은 3가지 개념이 사전에 필요하다.
가장 간단하게 설명하면
함수 내에 함수를 정의할 수 있다
함수를 인자로 전달할 수 있다.
내부(inner) 함수가 외부(outer) 함수의 인자를 기억하고 있는 것
*args(위치 인자)와 **kwargs(키워드 인자)
*args(위치인자) : 인자가 순서가 있음
## 위치 인자sum = 0for i in args:sum += ireturn sumprint()## 키워드 인자print("키워드인자를 출력 : ", kwargs)# print_kwargs('아침' : '시리얼', '점심' : '소고기', '저녁' : '없음')**kwargs(키워드인자)
Decorate 개념
decorator : 실내장식가
데커레이터(Decorator)는 하나의 함수를 취해서 또 다른 함수를 반환하는 함수이다.
코드는 이 블로그를 참조했다.
데코레이터 예제1 : 수동으로 활용하기
# 데코레이터 예제#1, #4#5 #8return #9return wrapper_function #6#2, #10print("display 함수가 실행됐습니다") #11decorated_display = #3 display 함수를 젇날#7
위 코드는 #
의 순서를 따른다.
#3
: decorated_display라는 변수는 decorated_function 함수의 리턴값을 할당받는다.#6
: return값은 wrapper_function이라는 함수다.#3
변수는 결국 함수를 실행시킬 수 있는 함수다.#7
: 변수가 함수니까 괄호를 붙여 실행시켜보자.#8
,#9
: return 값으로 original_function을 돌려준다.여기서 closure 함수의 개념이 쓰인다.
바깥 함수(decorator_function)에서 전달받은
original_function
을 기억하고 있다.
#10
,#11
: 여기서 비로소 함수를 실행하고, print문을 실행한다.
# 데코레이터 예제print("{} 함수가 호출되기 전입니다.".)returnreturn wrapper_functionprint("display_1 함수가 실행됐습니다.")print("display_2 함수가 실행됐습니다.")display_1 =display_2 =print(")
wrapper 함수를 통해서 간단하게 기능 추가를 할 수 있다.
데코레이터 예제2 : @
심볼 활용하기
# @ 심볼 활용하기print("{} 함수가 호출되기 전입니다.".)returnreturn wrapper_functionprint("display_1 함수가 실행됐습니다.")print("display_2 함수가 실행됐습니다.")# display_1 = decorator_function(display_1)# display_2 = decorator_function(display_2)# 변수에 함수형 리턴값 할당 없이 바로 함수 호출이 가능하다.# 변수에 함수형 리턴값 할당 없이 바로 함수 호출이 가능하다.
데코레이터 예제3 : 인자가 전달되는 함수는 어떻게 데코레이팅 할까?
예제1 : 위치인자와 키워드인자 활용하기
print("{} 함수가 호출되기 전입니다.".)returnreturn wrapper_functionprint("display_1 함수가 실행됐습니다.")# 위 예제와 다르게 인자가 전달된다.print("display_info( {}, {} ) 함수가 실행됐습니다.").# display_1 = decorator_function(display_1)# display_2 = decorator_function(display_2)>>> 출력결과> TypeError: takes 0 positional arguments but 2 were given
display_1 함수는 정상적으로 출력되지만, display_info
함수는 타입에러가 생겼다.
wrapper 함수에 위치인자와 키워드인자를 넣어주면 해결된다.
print("{} 함수가 호출되기 전입니다.".)returnreturn wrapper_function
예제2 : 위치인자와 키워드인자 활용하기
다음 예제는 Introducing Python
이라는 책에서 발췌한 예제이다.
여기서는 위치인자와 키워드인자까지 활용했다.
print('Running function : ', func.__name__)print('Positional arguments : ', args)print('Keyword arugments :' , kwargs)result =print('Result : ', result)return resultreturn new_functionreturn a + breturn a / badd =div =print()print(")print()>>> 출력값> Running function : add_inits> Positional arguments : (5, 3)> Keyword arugments :> Result : 8> 8> Running function : div_inits> Positional arguments : (5, 3)> Keyword arugments :> Result : 1.6666666666666667> 1.6666666666666667
그래서, 데코레이터를 언제 쓰는데?
로그를 남길 때
유저의 로그인 상태를 확인하여 로그인 페이지로 리다이렉트(redirect)
프로그램 성능을 위한 테스트
아직 제가 이정도를 논할 수준이 아니여서, 추후 포스팅하도록 하겠습니다.
대신, 좀 더 좋은 블로그를 소개하도록 하겠습니다.
파이썬 데코레이터를 작성하는 법을 배워야하는 5가지 이유(한빛미디어)
'프로그래밍 > 파이썬' 카테고리의 다른 글
[파이썬] get/set 속성값과 프로퍼티(property) (3) | 2017.05.23 |
---|---|
[파이썬] 제너레이터(Generator) 이해하기 (0) | 2017.05.21 |
[파이썬] 클로져(Closure) 이해하기 (1) | 2017.05.20 |
[파이썬] 일등 함수(first-class citizen) 이란? (2) | 2017.05.19 |
[파이썬] 리스트 컴프리헨션(list comprehension)의 이해 (1) | 2017.05.05 |