파이썬에는 decorator라는 기능이 있으며, 이 기능을 이용하면 기존에 존재하는 함수를 감싸서 추가기능을 덧붙여줄수있다. decorator라는 이름처럼 함수를 꾸며주는 기능이라고 보면 되겠다.
이 기능을 이해하기위해서는 파이썬 함수의 3가지 특징을 이해해야한다.
① 함수안에 함수를 선언하는 것이 가능하다.
② 함수의 인자로 함수를 전달하는것이 가능하다.
③ 함수 자체를 리턴하는것이 가능하다.
아래 outer_func 함수가 위 세가지 사례가 모두 담겨있는 예시이다. ① outer_func 함수는 target_func 이라는 함수를 인자로 전달받고 있고, ② 함수안에 inner_func이라는 함수를 선언하고있으며, ③ inner_func 함수를 리턴한다.
def outer_func(target_func):
def inner_func():
print('target 함수 실행 전 입니다.')
target_func()
print('target 함수 실행 후 입니다.')
return inner_func
위의 함수를 이용하면 결과적으로 outer_func의 인자함수인 target_func 함수 실행 전후로 로그를 찍을수 있다. 그러나, 위 함수를 그대로 사용하는것의 치명적인 단점은 기존의 함수 실행 코드를 모두 수정해주어야 한다는 점이다.
예를 들어 아래처럼 기존에 get_data()라는 함수를 선언하고 호출하는 코드가 있다고 했을때, 위 outer_func 함수를 이용해 함수 전후로 로그를 남기려면 아래처럼 함수 호출로직을 수정해주어야한다.
▼ as-is
def get_data():
print('func 함수를 시작합니다.')
get_data()
▼ to-be
def get_data():
print('func 함수를 시작합니다.')
a = outer_func(get_data)
a()
이는 매우 번거로우며, 이 문제는 decorator를 활용하면 쉽게 해결이 가능하다.
@outer_func
def get_data():
print('func 함수를 시작합니다.')
위처럼 함수 선언하는 부분위에 @outer_func (wrapping하는 함수명) 을 써주면, 함수 호출 방식을 하나씩 변경하지 않아도 알아서 wrapping하는 함수가 수행된다. 즉, 기존에 함수를 호출하는 방식을 유지해도 함수전후로 로그를 찍는 추가기능을 덧붙일수 있는 것이다.
사실, 위와같은 과정을 거치지 않더라도 get_data 함수를 직접 수정하면 함수 전후로 로그를 찍는 방식은 쉽게 구현할수 있다. 그러나 get_data와같은 함수 100개 존재하고, 해당 함수에 모두 동일한 추가기능을 적용하고 싶다면 함수를 하나씩 모두 수정하는것은 정말 번거롭다.
이때, decorator를 활용하면 함수를 하나씩 수정하여 로그를 남기는 기능을 심어주지않아도, 해당 기능을 일괄 적용하는것이 가능하다.
@outer_func
def get_data1():
print('func 함수를 시작합니다.')
@outer_func
def get_data2():
print('func 함수를 시작합니다.')
@outer_func
def get_data3():
print('func 함수를 시작합니다.')
get_data1()
get_data2()
get_data3()
'python' 카테고리의 다른 글
[python] OOP (0) | 2024.01.20 |
---|---|
[python] session과 cursor (0) | 2024.01.09 |