Decorator(데코레이터)
데코레이터(decorator)
개념
데코레이터는 함수의 앞과 뒤에서 실행되는 기능을 추가적으로 구현하고 싶을 때 사용한다.
형식
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def hello_decorator(func):
def decorated():
print("hello!")
func()
print("nice to meet you!")
return decorated
@hello_decorator
def hello():
print("I'm Hyuntae")
hello()
'''
Return :
hello!
I'm Hyuntae
nice to meet you!
'''
위의 코드를 살펴보자. 평범함 함수처럼 hello_decorator 라는 함수를 구현했다. 여기서 조금 특이한 점은 인수로서 함수의 이름을 받는다는 것이다. func이라는 함수를 인수로 받아서, hello_decorator 함수 중간에 func()을 실행한 바 있다.
사용하기 위해서는 다음과 같은 형식을 지켜야 한다.
1
2
3
4
5
6
def 데코레이터_이름(인수함수):
def 아무이름():
인수로_받은_함수_전에_실행할_내용()
인수함수()
인수로_받은_함수_후에_실행할_내용()
return 아무이름 #이때 소괄호를 붙이면 안된다.
이와 같은 방식을 지키면 된다.
사용방식
데코레이터를 사용할 때는 두 가지 방식이 있다.
1. @(‘at’)을 이용
맨 처음 위에서 예시를 들었던 것처럼 데코레이터를 붙일 함수 바로 위에다 @decorator_name 처럼 붙이는 것이다.
1
2
3
4
5
6
7
8
9
10
11
12
@hello_decorator
def hello():
print("I'm Hyuntae")
hello()
'''
Return :
hello!
I'm Hyuntae
nice to meet you!
'''
이 방식이면 그냥 함수만 호출해도 자연스럽게 데코레이터가 붙어서 실행된다.
2. 일반 함수처럼 사용
1
2
3
4
5
6
7
8
9
trace_hello = trace(hello) #데코레이터에 호출할 함수 넣고 저장
trace_hello() #데코레이터 호출
'''
Return :
hello!
I'm Hyuntae
nice to meet you!
'''
이 방법의 경우 데코레이터에 먼저 함수를 넣고, 그것을 새로운 함수 trace_hello에 저장한 후 실행해야 데코레이터 + 원래 함수가 실행된다.
데코레이터 여러 개 사용
데코레이터를 여러 개 사용하기 위해서는 위의 방식에서 조금만 변형하면 된다.
1번 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
@decorator1 #which print "decorator 1" ahead of the function
@decorator2 #which print "decorator 2" ahead of the function
def func():
print("it's function")
func()
'''
return :
decorator 1
decorator 2
it's function
'''
2번 방법
1
2
3
4
5
6
7
8
9
decorated_func = decorator1(decorator2(func))
decorated_func()
'''
return :
decorator 1
decorator 2
it's function
'''
위의 두 방식 모두 decorator 1이 실행된 이후 2가 실행된다. @ method의 경우 위에서부터 차례로 실행된다. 일반 함수처럼 쓰는 method에서는 바깥에서부터 안쪽 순으로 실행된다.
참고
데코레이터에서 함수의 이름을 가져올 때는 다음과 같은 방식을 취한다.
1
2
3
4
5
6
def trace(func):
def wrapper():
print(func.__name__, '함수 시작')
func()
print(func.__name__, '함수 끝')
return wrapper
인수를 func으로 받았다면 함수의 이름은 func.__name__으로 불러와서 사용할 수 있다.