프로그래밍/파이썬

[Python] 데코레이터 ( decorator )

고등어찌짐 2022. 7. 19. 21:46

 

데코레이터

데코레이터는 사용자가 기존 함수를 수정하지 않고, 새로운 기능을 추가할 수 있는 Python 의 디자인 패턴이다. 데코레이터를 이해하기 전에 알아야할 가장 중요한 것이 있다. 바로, 파이썬에서는 함수도 객체라는 것이다. 함수가 객체이기 때문에 다음 3가지도 파이썬에서는 가능하다. 

 

- 함수를 변수에 담을 수 있다. 

- 함수를 파라미터로 전달할 수 있다. 

- 함수 안에서도 함수를 정의할 수 있다. 

 

이 개념을 활용해 데코레이터 함수를 작성할 수 있다. 


데코레이터 이해하기

데코레이터의 정의에서 사용자가 기존 함수를 수정하지 않고, 새로운 기능을 추가할 수 있다는게 어떤 의미일까? 

 

인사를 하는 greeting 함수를 작성했다고 가정하자. 

def greeting():
   print("Nice to meet you.")
  
greeting()

# 출력결과
# Nice to meet you.

 

함수를 작성하고 나서 만나서 반갑다고 말하기 전 안녕, 그리고 헤어질 때 잘가 라고 말하고 싶다. 그럼 함수를 이렇게 수정해야할 것이다.

def greeting():
   print("Hello!")
   print("Nice to meet you.")
   print("Bye!")
   
greeting()

# 출력결과
# Hello!
# Nice to meet you.
# Bye!

 그런데 데코레이터를 이렇게 함수를 수정하는 것 말고, 기존의 greeting() 은 그대로 두면서 같은 결과를 얻을 수 있다. 

 

데코레이터에 대해 찾다보면  wrapper 함수를 사용한다고 나온다. 말 그대로 감싼다는 것인데 데코레이터 함수에 객체로 넘길 함수를 감싸 앞 뒤로 다른 기능을 붙일 수 있다고 생각하면 된다.

 

아래 작성한 예시 코드를 보자. 

def my_decorator(func):
    def wrapper():
        print("Hello!")
        func()
        print("Bye!")
    return wrapper

@my_decorator
def greeting():
    print("Nice to meet you.")

greeting()

 

출력결과 

Hello!
Nice to meet you.
Bye!

 

my_decorator 함수 안을 보면, func 이라는 파라미터를 받아 앞 뒤로 Hello! 와 Bye! 가 출력되고 있다. 그러니까 파라미터 func 는 그대로 사용하면서 앞 뒤에 내가 원하는 다른 기능을 붙일 수 있다 ( 감쌀 수 있다 ) 는 의미인 것이다. 

 

그런데 이 파라미터는 그냥 파라미터가 아니다. 앞서 파이썬에서 함수를 객체로 취급한다는 개념이 필요하다고 한 이유가 여기에 있다. 데코레이터 기호 @ 를 greeting 함수 위에 사용해 my_decorator 함수의 파라미터 func 에 함수를 넘겨준다. 그러면 func 으로 받은 함수 greeting 이 그대로 실행되는 것을 결과에서 볼 수 있다. 즉 기존의 greeting 함수를 수정하지 않고 기능을 덧붙일 수 있다. 

 


#참조

Python decorator? - can someone please explain this?

How to make function decorators and chain them together?