[Python] 데코레이터(Decorator)


Study/Python  2019. 12. 16. 20:02

안녕하세요. 명월입니다.


이 글은 Python에서 데코레이터에 대한 설명입니다.


이 전에 python의 모듈을 소개하고 표준 라이브러리의 모듈을 사용하는 것에 대해 소개했습니다. 이번에는 이 데코레이터에 대한 소개를 안 할 수가 없겠네요.

데코레이터는 함수를 재사용해서 함수의 상속(?)같은 기능이라고 생각하면 됩니다.


예를 들면 두개의 파리미터를 받아서 총 합계를 구하는 함수를 만들었습니다. 여기에 우리는 평균까지 구하고 싶다고 하면 함수를 수정해야 합니다만, 수정하지 않고 여기에 기능을 추가하는 기능으로 함수를 계속해서 사용할 수 있게 하는 방법입니다.

# 데코레이터 함수
def decorator_example(func):
  # 함수의 파라미터는 가변으로 설정한다.
  def function(*args, **kwargs):
    # 데코레이터로 지정된 함수를 실행하고
    ret = func(*args, **kwargs);
    # 그 결과를 리턴한다.
    return ret / (len(args) + len(kwargs));
  # 인라인 함수를 리턴한다.
  return function;

# 일반 더하기 함수이다.
def add(a,b):
  return a+b;
# 일반 더하기 함수를 호출하면 당연히 4+5의 결과 값인 9가 나온다.
c = add(4,5);
print(c);

# 위에서 설정한 데코레이터 함수를 지정합니다. 지정은 「@」마크다.
@decorator_example
def add2(a,b):
  return add(a,b);

# add2의 함수를 실행하면 데코레이터 함수로 넘어간다. 
# add2에서는 add함수를 사용했으므로 4+5의 9의 결과를 다시 데코레이터에서 9/파라미터의 개수 이므로 4.5의 결과가 나온다.
c = add2(4,5);
print(c);

# add3함수를 만들었다. 여기는 모든 수를 더하고 그 결과를 데코레이터로 넘긴다.
# 파라미터의 개수는 5개 이기 때문에 (a, b, c, d, e) / 5의 구성으로 결과가 나온다.
@decorator_example
def add3(a,b,c,d,e):
  return a+b+c+d+e;
# 1+2+3+4+5 = 15, 15/ 5 = 3의 결과가 나온다.
c = add3(1,2,3,4,5);
print(c);

실제로는 위처럼 사용하는 경우는 없습니다. 제가 데코레이터를 쉽게 설명(?)하기 위해 만든 것입니다.

보통 데코레이터는 callback함수나 함수의 사용 count, 로그를 위해서 사용합니다.

# 데코레이터에 파라미터를 넣을 수 있는데, 3중 인라인 함수로 구현이 가능하다.
# 첫번째 함수는 데코레이터의 파라미터
def callback(cb):
  # 두번째 함수는 데코레이터가 선언된 함수
  def wrapper(func):
    # 함수 호출 카운딩을 위한 변수
    count = 0;
    # 함수를 호출하는 데코레이터 부분
    def function(*args, **kwargs):
      nonlocal count;
      ret = func(*args, **kwargs);
      count += 1;
      # 데코레이터 파라미터가 function 타입이면 호출한다.
      if str(type(cb)) == "<class 'function'>":
        cb(count);
      return ret;
    return function;
  return wrapper;

# callback 데코레이터에 람다 함수를 넣었다.
@callback(lambda p : print("call back!! " + str(p)))
def add(a,b):
  return a+b;
# add 함수가 호출되면 lambda함수가 호출된다.
print(add(1,2));

# 람다 함수가 아닌 일반 함수로도 설정할 수 있다.
def attach_callback(count):
  print("call attach_callback!! " + str(count));

# callback 데코레이터에 attach_callback 함수를 넣었다.
@callback(attach_callback)
def add2(a,b):
  return a+b;

# add2함수가 호출되면 attach_callback 함수도 호출된다.
print(add2(1,2));
print(add2(1,2));
print(add2(1,2));
print(add2(1,2));
print(add2(1,2));
print(add2(1,2));

위 예제처럼 사용하면 add함수에 대한 호출시마다 로그를 남길 수도 있고, 데코레이터 측에서 보면 파라미터가 두개인 함수 뿐 아니라, 다른 여러 함수에서도 응용해서 사용할 수도 있습니다.

마지막에 attach_callback을 넣었는데 여기에 로그를 남기는 함수를 남기게 되면 여러가지로 사용할 수도 있습니다.


여기까지 Python에서 데코레이터에 대한 설명이었습니다.


궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.