Python 사용자 정의 함수에 대한 이해 2편 - Simple Decorator

Page content

공지

제 수업을 듣는 사람들이 계속적으로 실습할 수 있도록 강의 파일을 만들었습니다. 늘 도움이 되기를 바라며. 참고했던 교재 및 Reference는 꼭 확인하셔서 교재 구매 또는 관련 Reference를 확인하시기를 바랍니다.

I. 개요

  • FunctionsDecorators에 관해 나누려고 한다.
  • function는 우리가 생각하는 그 함수가 맞다.
  • decorator도 함수인데, 일종의 확장 개념으로 생각하면 좋다.
  • 지난 시간에 Python 사용자 정의 함수에 대한 이해 1편 - Inner Function를 통해 함수의 기본적인 작동 원리에 대해 배웠다.

II. Simple Decorators

  • Inner Function에 대해 기본적인 개념을 이해하였다면, 이번에는 decorator에 대해 빠르게 학습하는 시간을 준비하였다.
def simple_decorator(func):
  def wrapper():
    print("Before Function")
    func()
    print("After Function")
  return wrapper

def say_something():
  print("hay, say something")

say_something = simple_decorator(say_something)
say_something()
Before Function
hay, say something
After Function
  • 위 소스코드는 지난 시간에 배운 inner function의 개념이 들어가 있다.
  • 보통 decorator라고 말할 수 있는 시점은 say_something = simple_decorator(say_something) 이다.
  • say_something 함수는 wrapper() 함수 안에 있는 inner function을 의미한다.
say_something
<function __main__.simple_decorator.<locals>.wrapper>
  • 그런데, wrapper()는 원래의 say_something()func로 언급하고 있으며, 그 기능을 두 사람 사이에 print()를 호출 한다.
  • 조금 쉽게 말하면: decorators wrap a function, modifying its behavior.
  • 다음 단계로 넘어가기 전에 두 번째 예를 살펴 본다.
    • wrapper()는 일반적인 Python 함수이기 때문에, decorator가 함수를 수정하는 방식은 보다 역동적으로 변할 수 있다.
    • 10시가 넘어가면 함수 호출이 금지하는 것을 짜보도록 한다.
from datetime import datetime
print("the current time is : {nowtime}H".format(nowtime = datetime.now().hour))

def do_not_disturb_me(func):
  def wrapper():
    if 7 <= datetime.now().hour < 10:
      func()
    else:
      pass # 10시가 넘어갔습니다. 지금 11시입니다. 
  return wrapper

def say_loudly():
  print("Hey~~~~~!")

say_loudly = do_not_disturb_me(say_loudly)
say_loudly()
the current time is : 11H
  • 10시가 넘어갔기 때문에, 아무일도 일어나지 않는다.

III. Pie Syntax

  • decorator가 사용되기는 했지만,
say_loudly = do_not_disturb_me(say_loudly)
say_loudly()
  • 즉, 코드의 길이가 길다는 단점이 있다.
    • 이 때, 보통 @symbol을 사용하면 보다 쉽게 사용할 수 있다.
    • 아래코드를 실행하면 위 2줄의 코드가 실행된 것과 똑같이 결과값이 나온다.
from datetime import datetime
print("the current time is : {nowtime}H".format(nowtime = datetime.now().hour))

def my1st_decorator(func):
  def wrapper():
    if 7 <= datetime.now().hour < 10:
      func()
    else:
      pass # 10시가 넘어갔습니다. 지금 11시입니다. 
  return wrapper

@my1st_decorator
def say_loudly():
  print("Hey~~~~~!")
the current time is : 11H
  • 이제 다음시간에는 모듈을 활용하여 decorator의 재사용성에 대해 확인해보는 시간을 갖는다.

IV. Reference

Hjelle, G. A. (2020, May 04). Primer on Python Decorators. Retrieved June 10, 2020, from https://realpython.com/primer-on-python-decorators