Python @ (decorator) 왕초보를 위한 Python 문법 익히기 2020-06-13 신달수 0 댓글 0 147 뭔가? 데코레이터 꾸며주다 한마디로 대상 함수를 wrapping하고, 이 wrapping된 함수의 앞뒤에 추가적으로 꾸며질 구문들을 정의해서 손쉽게 재사용 가능하게 해주는 것 왜 쓰나? # 만약, 이런코드가 기존에 존재했다고 칩시다. import datetime def main_function(): print(datetime.datetime.now()) print("Main Function Start") print(datetime.datetime.now()) def main_function_1(): print('Main Function 1 Start') def main_function_2(): print('Main Function 2 Start') def main_function_3(): print('Main Function 3 Start') ... 100번 반복된 소스코드 (이미 구현되어 가동되고 있는 소스라고 가정) # 위의 반복되는 소스코드에 앞뒤로 날짜를 찍어주는 기능을 구현한다고 가정합시다. import datetime def main_function_1(): print datetime.datetime.now() print "MAIN FUNCTION 1 START" print datetime.datetime.now() def main_function_2(): print datetime.datetime.now() print "MAIN FUNCTION 2 START" print datetime.datetime.now() def main_function_3(): print datetime.datetime.now() print "MAIN FUNCTION 3 START" print datetime.datetime.now() 이런 코드를 100번 넣어야겠지요. 반복되는 구문이 많아지다 보니 점점 소스가 지저분해지고 가독성도 떨어집니다. 함수(def)를 통한 활용 import datetime def datetime_decorator(func): def decorated(): print datetime.datetime.now() func() print datetime.datetime.now() return decorated @datetime_decorator def main_function_1(): print "MAIN FUNCTION 1 START" @datetime_decorator def main_function_2(): print "MAIN FUNCTION 2 START" @datetime_decorator def main_function_3(): print "MAIN FUNCTION 3 START" 100번 반복 decorator 함수를 재사용 함으로써, main 함수에 대한 가독성과 직관성이 훨씬 좋아진 것을 볼 수 있다. 그리고 같은 패턴을 여러번 사용하더라고 간단히 @를 붙이면 끝이므로 사용도 간편하다. 원리1 먼저 decorator 역할을 하는 함수를 정의하고, 이 함수에서 decorator가 적용될 함수를 인자로 받는다. python 은 함수의 인자로 다른 함수를 받을 수 있다는 특징을 이용하는 것이다. 원리2 decorator 역할을 하는 함수 내부에 또 한번 함수를 선언(nested function)하여 여기에 추가적인 작업(시간 출력) 을 선언해 주는 것이다. 원리3 nested 함수를 return 해주면 된다. 클래스(class)를 통한 활용 import datetime class DatetimeDecorator: def __init__(self,f): self.func = f def __call__(self,*args,**kwargs): print(datetime.datetime.now()) self.func(*args,*kwargs) print(datetime.datetime.now()) class MainClass: @DatetimeDecorator def main_function_1(): print("Main Function 1 Start") @DatetimeDecorator def main_function_2(*args,**kwargs): print("Main Function 2 Start") @DatetimeDecorator def main_function_3(): print("Main Function 3 Start") my = MainClass() my.main_function_1() my.main_function_2('a',b='1')