python 으로 작성된 다른 코드들을 보다보면 아래와 같이 어느 함수 위에 @ 가 있는 걸 볼 수 있습니다. 이 @ 는 무엇을 나타내고 어떤 역할을 하지는 알아보도록 합시다.
@decorator
def function1():
print("ssungkang")
제목에서 알 수 있듯이 이것이 바로 decorator 입니다. 사실 데코레이터가 없다고 해서 구현을 못하는 일이 생기는 건 아니지만 코드가 복잡해집니다. 즉 사용자가 편리해지기 위한 것 이라고 생각하면 됩니다. 지금부터 decorator 에 대해서 알아보도록 하겠습니다.
decorator 는 사실 하나의 함수입니다. 어떤 함수냐면 다른 함수를 감싸고 있는 함수죠. 아래 예시를 봐보도록 합시다.
def decorator(func):
def deco_func():
print("velog")
func()
return deco_func
def function1():
print("donghyeok")
function1 = decorator(function1)
function1()
velog
donghyeok
기존의 function1 함수는 단순히 donghyeok 만을 출력하는 함수입니다. 이 함수를 decorator 라는 함수에 씌어준 결과, 기존의 출력 이외에 tistory 라는 출력도 포함합니다. 코드가 어렵지는 않으나 함수를 매개변수로 받고 그 안에 함수를 또 만들고 그 함수를 반환하게 됩니다. 생각보다 이러한 작업은 범용적으로 많이 쓰이며 쓰지 않는 라이브러리를 찾기가 힘들 정도입니다. 그래서 이를 간결하게 하기 위해서 파이썬은 decorator 를 지원해줍니다.
def decorator(func):
def deco_func():
print("velog")
func()
return deco_func
@decorator
def function1():
print("donghyeok")
function1()
velog
donghyeok
다음과 같이 @ + 감싸주는 함수이름을 함수 위에 적어줄 경우, 위와 같은 효과를 가져 올 수 있습니다.
복잡한 코드가 여러 함수에 중복적으로 들어가야할 경우 decorator 를 통해서 단순화 해 줄 수 있습니다.
이번에는 위의 코드를 조금 응용해서 각 함수마다 tistory 를 출력하는 횟수가 달라야 한다고 가정해보겠습니다. 그러면 장식자는 인자를 받아야 할 것입니다.
우선 장식자를 사용하지 않은 코드입니다.
def decorator(n):
def outer(func):
def deco_func():
for i in range(n):
print("velog")
func()
return deco_func
return outer
def function1():
print("donghyeok")
decorator_3 = decorator(3)
function1 = decorator_3(function1)
function1()
velog
velog
velog
donghyeok
기존 decorator 가 하던 함수를 받는 역할을 outer 가 대신 해주고 이번에는 decorator 는 n 값을 받아서 그 n 값 만큼 출력을 반복하는 새로운 함수를 반환하게 됩니다. 이를 장식자로 사용하는 것도 똑같은 원리로 적용해주면 됩니다.
def decorator(n):
def outer(func):
def deco_func():
for i in range(n):
print("velog")
func()
return deco_func
return outer
@decorator(3)
def function1():
print("donghyeok")
function1()
velog
velog
velog
donghyeok