-
[코딩도장] day28. 파이썬 데코레이터(1/2) - @데코레이터, def데코레이터IT/파이썬 2020. 9. 22. 00:02
■ 들어가기
- 파이썬 코딩 도장 (남재윤/길벗). 을 공부하며 정리하는 블로그
▶ Unit42. 데코레이터 사용하기
- 42.1 데코레이터 만들기
- 42.2 매개변수와 반환값을 처리하는 데코레이터 만들기
- 42.3 매개변수가 있는 데코레이터 만들기
- 42.4 클래스로 데코레이터 만들기
- 42.5 클래스로 매개변수와 반환값을 처리하는 데코레이터 만들기
0. 들어가기
- 데코레이터(decorator) : 클래스 내 메서드를 장식하는 도구 (표기: @)
- 사용예시
class Calc :
@staticmethod # 데코레이터
def add(a, b) :
print(a + b)
>> 42.1 데코레이터 만들기 <<
- 데코레이터는 함수를 수정하지 않은 상태에서 추가 기능 구현 시 사용
- 예제 : 함수 시작, 끝을 출력하는 기능 구현
설명 : 일반적인 함수 작성 소스 (function_begin_end.py) 결과 def hello() :
print('hello 함수 시작')
print('hello')
print('hello 함수 끝')
def world() :
print('world 함수 시작')
print('world')
print('world 함수 끝')
hello()
world()hello 함수 시작
hello
hello 함수 끝
world 함수 시작
world
world 함수 끝설명 : 데코레이터를 활용한 함수 소스 (decorator_closure.py) 결과 def trace(func) : # 호출할 함수를 매개변수로 받음
def wrapper() : # 호출할 함수를 감싸는 함수
print(func.__name__, '함수 시작') # __name__으로 함수 이름 출력
func() # 매개변수로 받은 함수를 호출
print(func.__name__, '함수 끝')
return wrapper # wrapper 함수 반환
def hello() :
print('hello')
def world() :
print('world')
trace_hello = trace(hello) # 데코레이터에 호출할 함수를 넣음
trace_hello() # 반환된 함수를 호출
trace_world = trace(world) # 데코레이터에 호출할 함수를 넣음
trace_world() # 반환된 함수를 호출hello 함수 시작
hello
hello 함수 끝
world 함수 시작
world
world 함수 끝1. @으로 데코레이터 사용하기
- 사용법
@데코레이터
def 함수이름() :
코드
소스 (decorator_closure_at_sign.py) 결과 def trace(func) : # 호출할 함수를 매개변수로 받음
def wrapper() :
print(func.__name__, '함수 시작') # __name__으로 함수 이름 출력
func() # 매개변수로 받은 함수를 호출
print(func.__name__, '함수 끝')
return wrapper
@trace # @데코레이터
def hello() :
print('hello')
@trace # @데코레이터
def world() :
print('world')
hello() # 함수를 그대로 호출
world() # 함수를 그대로 호출hello 함수 시작
hello
hello 함수 끝
world 함수 시작
world
world 함수 끝- 그러면 trace라는 함수말고 다른 이름의 함수 만들고 해당 함수 이름으로 @ 데코레이터 붙히면 어떻게 될까??
- 결론 : 된다!!!! // 데코레이터 이름의 함수를 만들고 데코레이터로 호출하면 처리 가능하구나!! 그렇지 않으면 NameError 발생!
소스 (decorator_closure_at_sign2.py) 결과 def abc(func) : # 호출할 함수를 매개변수로 받음
def wrapper() :
print(func.__name__, '함수 시작') # __name__으로 함수 이름 출력
func() # 매개변수로 받은 함수를 호출
print(func.__name__, '함수 끝')
return wrapper
@abc # @데코레이터
def hello() :
print('hello')
@abc # @데코레이터
def world() :
print('world')
hello() # 함수를 그대로 호출
world() # 함수를 그대로 호출hello 함수 시작
hello
hello 함수 끝
world 함수 시작
world
world 함수 끝>> 42.2 매개변수와 반환값을 처리하는 데코레이터 만들기 <<
- 매개변수와 반환값을 처리하는 데코레이터 확인
- 실제 호출할 함수의 매개변수와 wrapper 함수의 매개변수를 똑같이 만들어줌
소스 (decorator_param_return.py) 결과 def trace(func) :
def wrapper(a, b) :
r = func(a, b)
print('{0}(a={1}, b={2}) -> {3}'.format(func.__name__, a, b, r))
return r
return wrapper
@trace
def add(a, b) :
return a + b
print(add(10, 20))add(a=10, b=20) -> 30
301. 가변 인수 함수 데코레이터
- 매개변수(인수)가 고정되지 않은 함수 처리 방법은?
-> wrapper 함수를 가변 인수 함수로 만들면 된다.
소스 (decorator_variable_argument.py) 결과 def trace(func) : # 호출할 함수를 매개변수로 받음
def wrapper(*args, **kwargs) : # 가변 인수 함수로 만듦
r = func(*args, **kwargs) # func에 args, kwrargs를 언패킹하여 넣어줌
print('{0}(args={1}, kwargs={2}) -> {3}'.format(func.__name__, args, kwargs, r)) # 매개변수와 반환값 출력
return r # func의 반환값을 반환
return wrapper # wrapper 함수 반환
@trace # @데코레이터
def get_max(*args) : # 위치 인수를 사용하는 가변 인수 함수
return max(args)
@trace # @데코레이터
def get_min(**kwargs) : # 키워드 인수를 사용하는 가변 인수 함수
return min(kwargs.values())
print(get_max(10, 20))
print(get_min(x=10, y=20, z=30))get_max(args=(10, 20), kwargs={}) -> 20
20
get_min(args=(), kwargs={'x': 10, 'y': 20, 'z': 30}) -> 10
10- get_max, get_min 함수는 가변 인수 함수로써, get_max 함수는 튜플로, get_min 함수는 딕셔너리(key-value)로 데이터 전달
- args 는 튜플, kwargs는 딕셔너리
'IT > 파이썬' 카테고리의 다른 글
[코딩도장] day30. 파이썬 정규표현식 사용하기 - re, *, +, match (0) 2020.09.29 [코딩도장] day29. 파이썬 데코레이터(2/2) (0) 2020.09.26 [코딩도장] day27. 파이썬 코루틴 - next, send, yield (0) 2020.09.21 [코딩도장] day27. 파이썬 제너레이터 사용하기 - yield (0) 2020.09.21 [코딩도장] day27. 파이썬 이터레이터 사용하기 - __iter__, __next__, __getitem__ (0) 2020.09.21