42.7 연습문제: 데코레이터로 매개변수의 자료형 검사하기
다음 소스 코드에서 데코레이터 type_check를 작성하세요. type_check는 함수의 매개변수가 지정된 자료형(클래스)이면 함수를 정상적으로 호출하고, 지정된 자료형과 다르면 RuntimeError 예외를 발생시키면서 '자료형이 다릅니다.' 에러 메시지를 출력해야 합니다. 여기서 type_check에 지정된 첫 번째 int는 호출할 함수에서 첫 번째 매개변수의 자료형을 뜻하고, 두 번째 int는 호출할 함수에서 두 번째 매개변수의 자료형을 뜻합니다.
practice_decorator.py
... @type_check(int, int) def add(a, b): return a + b print(add(10, 20)) print(add('hello', 'world'))
실행 결과
30 Traceback (most recent call last): File "C:\project\practice_decorator.py", line 16, in <module> print(add('hello', 'world')) File "C:\project\practice_decorator.py", line 7, in wrapper raise RuntimeError('자료형이 올바르지 않습니다.') RuntimeError: 자료형이 올바르지 않습니다.
정답
def type_check(type_a, type_b): def real_decorator(func): def wrapper(a, b): if isinstance(a, type_a) and isinstance(b, type_b): return func(a, b) else: raise RuntimeError('자료형이 올바르지 않습니다.') return wrapper return real_decorator
해설
데코레이터 type_check를 보면 @type_check(int, int)와 같이 int 두 개를 넣고있습니다. 따라서 매개변수가 있는 데코레이터입니다.
먼저 def type_check(type_a, type_b):와 같이 데코레이터가 사용할 매개변수를 지정합니다. 그리고 type_check 함수 안에서는 실제 데코레이터 역할을 하는 real_decorator를 만듭니다. 특히 이 함수에서 def real_decorator(func):와 같이 호출할 함수를 매개변수로 받습니다.
add 함수는 def add(a, b):와 같이 매개변수를 두 개 받으므로 wrapper 함수도 def wrapper(a, b):와 같이 매개변수를 두 개 지정해줍니다. 그다음에 isinstance를 사용하여 호출할 함수의 매개변수가 데코레이터에 지정한 자료형(클래스)의 인스턴스인지 확인합니다. 인스턴스가 맞으면 return func(a, b)와 같이 함수를 호출한 뒤 결과를 반환하고, 인스턴스가 아니면 raise RuntimeError('자료형이 올바르지 않습니다.')와 같이 예외를 발생시키면서 에러 메시지를 출력합니다.
마지막으로 wrapper 함수를 다 만들었으면 return으로 wrapper 함수를 반환하고, real_decorator 함수를 다 만들었으면 return으로 real_decorator 함수를 반환하면 됩니다.