decorator

  • 쉽게 기능을 추가할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # 처음 함수를 정의할 때 쓰는 *의 의미는 가변인자를 사용한다는 의미이다.
    # 함수를 호출할 때 쓰는 *의 의미는 unpacking을 의미한다.(tuple, dictionary)

    def outer(org_func):
    def inner(*args, **kwargs):
    # 추가되는 기능
    print("여기에 기능 추가")
    return org_func(*args, **kwargs)
    return inner


    def func(a, b):
    return a + b


    func.__name__
    >> 'func'
    • 일반적인 기능 추가

      1
      2
      3
      4
      5
      6
      7
      8
      func = outer(func) # inner
      func.__name__
      >> 'inner'


      func(4, 6)
      >> 여기에 기능 추가
      10
    • 데코레이터를 사용한 기능 추가

      1
      2
      3
      4
      5
      6
      7
      @outer
      def func(a, b):
      return a + b

      func(4, 6)
      >> 여기에 기능 추가
      10
  • 데코레이터를 사용하여 경과 시간 측정 함수 기능 추가

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    from functools import wraps
    import time

    def benchmarker(org_func):
    @wraps(org_func)
    def inner(*args, **kwargs):
    start = time.time()
    result = org_func(*args, **kwargs)
    elapsed = time.time() - start
    print(f'elapsed time : {elapsed:.2f}')
    return result
    return inner


    @benchmarker
    def something(a, b):
    time.sleep(2) # C언어에서는 ms이지만 python에서는 sec이다.
    return a + b


    something(1, 2)
    >> elapsed time : 2.00
    3


    something.__name__
    >> 'something'

    # wraps()를 사용하면 원래 함수의 이름을 가질 수 있다.
    # wraps()를 사용하지 않으면 something의 이름은 inner가 된다.
  • 데코레이터를 사용하여 callcounter 함수 기능 추가

    • 어떤 함수를 호출한 횟수를 보여주는 함수
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      g_call_num = 0

      def callcounter(org_func):
      @wraps(org_func)
      def inner(*args, **kwargs):
      global g_call_num
      g_call_num += 1
      print(f'{g_call_num}번 호출되었습니다.')
      return org_func(*args, **kwargs)
      return inner


      @callcounter
      def func(a, b):
      return a + b


      for _ in range(10):
      print(func(10, 5))

      >> 1번 호출되었습니다.
      15
      2번 호출되었습니다.
      15
      3번 호출되었습니다.
      15
      4번 호출되었습니다.
      15
      5번 호출되었습니다.
      15


      #경과 시간 측정 함수까지 기능 추가
      @benchmarker
      @callcounter
      def another_func(a, b):
      return a + b


      another_func.__name__
      >> 'another_func'


      another_func(10, 2)
      >> 6번 호출되었습니다.
      elapsed time : 0.00
      12
Share