Decorator
- 기존 함수에 기능을 추가하여 새로운 함수를 만듬
- Closure function을 활용
- https://www.python.org/dev/peps/pep-0318/
- decorator 사용 이유는? 함수 혹은 메쏘드에 새로운 기능을 추가하기 위해!
- 그렇다면 왜 소스 코드를 수정하지 않는가? 여러 함수에 동일한 기능을 추가할 수 있다.
예를 들면, 모든 함수에 전달된 파라미터의 유효성 검사가 필요하다고 가정했을때, 유효성 검사 코드가 각 함수마다 복사되면 수정의 어려움이 존재한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 |
# decorator 함수 정의
def decorate_func(function):
def inner():
print('decoration added')
function()
return inner
def simple():
print('simpel function')
# 일반 함수 호출
simple()
print('='*20)
# simple 함수에 기능을 추가한(decorate 한) decorated 함수
decorated = decorate_func(simple)
# 결과가 decoration 됨
decorated()
==================<<실행결과>>==================
simpel function
====================
decoration added
simpel function
|
cs |
'@'심볼 사용
- decorator를 생성하기 위한 syntactic sugar (문법적 편의성)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
# decorator 함수 정의
def decorate_func(function):
def inner():
print('decoration added')
function()
return inner
def simple():
print('simple function')
# 사실 귀찮고, python 답지 않은 문법임
simple = decorate_func(simple)
simple()
==================<<실행결과>>==================
decoration added
simple function |
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 |
# decorator 함수 정의
def decorate_func(fn):
def inner():
print('decoration added')
fn()
return inner
# 아래와 같이 @를 사용하여 decoration 가능!
# 기능을 추가하는 것이라고 이해하면 된다.
@decorate_func
def simple():
print('simple function')
# 결과가 decorated 됨!
simple()
==================<<실행결과>>==================
decoration added
simple function |
cs |
파라미터가 있는 함수 Decorator
- 중첩함수에 꾸미고자 하는 함수와 동일하게 파라미터를 가져가면 됨
case1) '@' 기호를 쓰지 않은 경우
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 |
def decorate_divide(fn):
def wrapper(a, b):
if b == 0:
print('zero cannot be divided!')
return
return fn(a, b)
return wrapper
def divide(a, b):
return a / b
divide = decorate_divide(divide)
print(divide(9, 3))
print(divide(9, 0))
==================<<실행결과>>==================
3.0
zero cannot be divided!
None |
cs |
case2) '@' 기호를 쓰는 경우
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 |
def decorate_divide(fn):
def wrapper(a, b):
if b == 0:
print('zero cannot be divide!')
return
return fn(a, b)
return wrapper
# '@' 기호를 아래와 같이 사용 할 것!
@decorate_divide
def divide(a, b):
return a / b
print(divide(9, 0))
print('='*20)
print(divide(81, 7))
==================<<실행결과>>==================
zero cannot be divide!
None
====================
11.571428571428571 |
cs |
모든 함수에 대한 Decorator
- 모든 함수의 파라미터는 (*args, ***kwargs)로 표현 가능하다. 따라서 내부함수의 파라미터를 (*args, ***kwargs)로 구성하면 어떠한 함수도 decoration 가능
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 |
def general_decorator(fn):
def wrapper(*args, **kwargs):
print('function is decorated..')
return fn(*args, **kwargs)
return wrapper
@general_decorator
def add(a, b):
return a + b
@general_decorator
def print_hello():
print('hello')
print(add(4, 5))
print('=' * 20)
print_hello()
==================<<실행결과>>==================
function is decorated..
9
====================
function is decorated..
hello |
cs |
반응형
'Python > Python Basic' 카테고리의 다른 글
Pickle 모듈 (0) | 2017.09.30 |
---|---|
Decorator_03 (Decorator Chaining, Method decoration, Decorator with parameters) (0) | 2017.09.30 |
Decorator_01 (Nested function, Closure) (0) | 2017.09.30 |
Class] 2. 정보은닉(private, protected, public) (0) | 2017.06.15 |
Class] 1. __init__ & method (0) | 2017.06.15 |