TIL #73 : [Python] Decorator (매개변수 有)🧤

셀레스틴 허·2021년 2월 14일
0
post-thumbnail

🧤 함수로 장식하자!

매개변수가 있는 데코레이터


이런 방식의 데코레이터는 값을 지정해서 동작을 바꿀 수 있다는게 큰 장점이다.

매개변수가 있는 데코레이터는 어떻게 호출될까?

코드

def decoratorFunctionWithArguments(arg1, arg2, arg3):
    def wrap(f):
        print("wrap() 속에 들어왔습니다.")
        def wrapped_f(*args):
            print("wrapped_f() 속에 들어왔습니다.")
            print("데코레이터 arguments:", arg1, arg2, arg3)
            f(*args)
            print("f(*args) 후.")
        return wrapped_f
    return wrap

@decoratorFunctionWithArguments("hello", "world", 42)
def sayHello(a1, a2, a3, a4):
    print('sayHello arguments:', a1, a2, a3, a4)

print("데코레이터 후!")

print("sayHello() 콜 준비중.")
sayHello("안녕하세요", "sayHello", "argument", "list")
print("sayHello() 첫번째 콜 후.")
sayHello("반갑습니다", "sayHello의", "다른", "arguments")
print("sayHello() 두번째 콜 후.")

실행 결과

wrap() 속에 들어왔습니다.
데코레이터 후!
sayHello() 콜 준비중.
wrapped_f() 속에 들어왔습니다.
데코레이터 arguments: hello world 42
sayHello arguments: 안녕하세요 sayHello argument list
f(*args) 후.
sayHello() 첫번째 콜 후.
wrapped_f() 속에 들어왔습니다.
데코레이터 arguments: hello world 42
sayHello arguments: 반갑습니다 sayHello의 다른 arguments
f(*args) 후.
sayHello() 두번째 콜 후.
  1. decoratorFunctionWithArguments() 안에 있는 wrapper 함수 wrap()에 들어간다.
  2. 데코레이터 실행후 sayHello() 콜을 준비한다.
  3. 그리고 바로 다시 wrapped_f() 속으로 들어간다.
  4. 데코레이터의 args - "hello", "world", 42 - 를 출력한다.
  5. 그리고 이제 sayHello의 args - 안녕하세요, sayHello, argument, list를 출력한다.
  6. sayHello의 args까지 출력하면 이제 첫번째 콜은 끝났다.
  7. 다시 wrapped_f()으로 들어간다.
  8. 데코레이터의 args - "hello", "world", 42 - 를 출력한다.
  9. 그리고 이제 두번째 sayHello의 args - 반갑습니다, sayHello의, 다른, arguments를 출력한다.
  10. 두번째 sayHello의 args까지 출력하면 두번째 콜도 끝났다.

ex) 함수의 반환값이 특정 수의 배수인지 확인하는 데코레이터

코드

def is_multiple(x):
  def real_decorator(func): # 실제 데코레이터 역할
    def wrapper(a,b):
      r = func(a,b)

      if r % x == 0:
        print('{0}의 반환값은 {1}의 배수입니다.'.format(func.__name__, x))

      else:
        print('{0}의 반환값은 {1}의 배수가 아닙니다.'.format(func.__name__, x))

      return r
    return wrapper
  return real_decorator

@is_multiple(3)
def add(a, b):
  return a + b

print(add(10, 20))
print(add(2, 5))
  1. 데코레이터가 사용할 매개변수(x)를 정한다.
  2. 호출할 함수를 매개변수로 받는다(func).
  3. 호출할 함수의 매개변수와 똑같이 지정(a, b)한다.
  4. func를 호출하고 반환값을 변수에 저장한다.
  5. func의 반환값이 x의 배수인지 확인한다. (r % x == 0)
  6. func의 반환값을 반환한다.
  7. wrapper 함수 반환한다.
  8. real_decorator 함수 반환한다.

실행 결과

add의 반환값은 3의 배수입니다.
30
add의 반환값은 3의 배수가 아닙니다.
7

Reference:
https://www.artima.com/weblogs/viewpost.jsp?thread=240845#decorator-functions-with-decorator-arguments
https://dojang.io/mod/page/view.php?id=2429

profile
Software Developer / 고통은 필연, 괴로움은 선택

2개의 댓글

comment-user-thumbnail
2021년 11월 9일

우연히 온 벨로그가 민지님 블로그였다니~~!!

1개의 답글