상세 컨텐츠

본문 제목

데코레이터 (Decorator) - 개념, 장단점, 예시

개발/python-객체지향프로그래밍(OOP)

by Matthew0633 2022. 5. 10. 23:44

본문

데코레이터를 수월하게 이해하기 위해서는 클로저(Closure) 와 일급함수(First-class Function)의 개념을 익히는 것이 필요하다. 리마인딩을 위해 해당 부분을 정리한 포스팅 링크를 첨부하자!!

 

클로저 (Closure) (1) - 일급함수 (First-class function)

일급함수 (First-class function) In computer science, a programming language is said to have first-class functions if it treats functions as first-class citizens. This means the language supports pas..

matthew0633.tistory.com

 

 

클로저 (Closure) (2) - 클로저 개념 및 구현

클로저 (Closure) (Closure in Wiki) In programming languages, a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with fir..

matthew0633.tistory.com

데코레이터 (Decorator)

여러개의 함수 내에 동일한 기능을 추가해야할 때, 혹은 이와 같은 상황이 예상될 때 이를 간편하고 효율적으로 프로그래밍할 수 있게하는 개념이 데코레이터이다

데코레이터 사용의 장점

  • 여러 함수들을 꾸며줄 공통함수를 작성함으로써 중복이 제거되어 코드가 간결해진다
  • 예) 로깅, 프레임워크, 유효성 체크와 같은 기능을 공통기능으로 분리해놓고, 대상 함수에 간편하게 적용 가능하다 (일일이 코드를 복사 붙여넣기할 필요가 없다)

데코레이터 사용의 단점

  • 특수적인 형태를 띄고 있어, 초심자에게는 코드의 로직이 바로 보이지 않아 가독성이 감소할 수 있다
  • 데코레이터를 사용하지 않았을 때보다 디버깅이 좀 더 불편해질 수 있다

데코레이터 사용 예시 : 소요시간 출력 기능 추가를 위한 함수

현재 나는, 인자들의 합을 반환하는 sum_func 함수에 실행시간 출력 기능을 덧입히고 싶다. 그리고 앞으로 정의할 많은 함수에도 해당 기능을 반복적으로 추가해야할 일이 예상되는 상황이라면..? 데코레이터가 효율적인 도구가 될 수 있다

이 때, 만약 데코레이터를 사용하지 않는다면 아래 코드와 유사하게 작성이 될 것이다. 대상 함수를 인자로 받으며, 실행시간 출력 함수를 반환하는 perf_clock 함수에 두 함수를 각각 넣어준 함수로 다시 변수에 할당해야 한다.

import time

def perf_clock(func):
    def perf_clocked(*args):
        # 함수 시작 시간 
        st = time.perf_counter() 
        result = func(*args)
        # 함수 종료 시간 계산
        et = time.perf_counter() - st 
        # 실행 함수명
        name = func.__name__
        # 함수 매개변수 
        arg_str = ', '.join(repr(arg) for arg in args)
        # 결과 출력
        print('[%0.5fs] %s(%s) -> %r' % (et, name, arg_str, result)) 
        return result 
    return perf_clocked

def sum_func(*numbers):
    return sum(numbers)

# 데코레이터 미사용
sum_func = perf_clock(sum_func)

sum_func(100, 150, 250, 300, 350) # 1150

그런데, 데코레이터를 사용하면, 아래와 같이 대상 함수를 정의할 때, 한줄만 추가되고, 곧바로 정의된 함수가 소요시간 출력 기능을 갖게 된다

즉, 함수를 소요시간 출력 기능을 가진 클로저 함수내에 넣어주며, 다시 변수에 할당해야할 필요가 없어진다

# 데코레이터 사용

@perf_clock
def sum_func(*numbers):
    return sum(numbers)

sum_func(100, 150, 250, 300, 350) # 1150

관련글 더보기

댓글 영역