[Python] Decorator (2)
Decorator (2)
Deoorator 의 기본적인 것은 Decorator 1 에서 다루었으니 참고하길 바란다.
Step. 1
def deco_func(origin_func): # 데코레이터 함수
def nested_func(*args, **kwargs):
print("계산 시작합니다.")
origin_func(*args, **kwargs)
print("계산 완료되었습니다.")
return
return nested_func
@deco_func
def output(a, b):
print(a + b)
[Python] Decorator (1) 에서 사용했던 예시코드이다.
위 코드에서의 불완전 요소는 값을 반환받지 못한다는 점이다.
output(3,7)
>>> '계산 시작합니다.'
>>> '10'
>>> '계산 완료되었습니다.'
type(output(3,7))
>>> NoneType
output
함수의 결과는 아무런 값도 반환받지 못한다. return
을 통해 반환받은 값이 없기 때문이다.
Step. 2
위의 문제를 해결하기 위해서
output
함수의 print
를 return
으로 바꾼다.
def deco_func(origin_func): # 데코레이터 함수
def nested_func(*args, **kwargs):
print("계산 시작합니다.")
origin_func(*args, **kwargs)
print("계산 완료되었습니다.")
return
return nested_func
@deco_func
def output(a, b):
return(a + b) # print 에서 return 으로 변환
output(3,7) # 함수 실행
>>> '계산 시작합니다.'
>>> '계산 완료되었습니다.'
type(output(3,7))
>>> NoneType
현재 문제점
- 계산 시작과 완료 사이에 결과값이 출력되지 않았다.
output(3,7)
의 값이 여전히NoneType
이다.
원인
deco_func
함수의 중첩함수 nested_func
내부에서 output
함수가 실행되고 return
이 됨에따라 반환은 되었다.
하지만 반환된 곳은 nested_func
함수 내부이며, nested_func
는 어떤 값도 반환하지 않았다.
이에따라 output
함수의 값은 최종적으로 반환되지 못한다.
이 문제를 해결하기 위해서는 nested_func
함수 내부에서 origin_func(*args, **kwargs)
를 반환해주어야 한다는 것을 알 수 있다.
문제를 해결하기 위한 실험코드
def deco_func(origin_func): # 데코레이터 함수
def nested_func(*args, **kwargs):
print("계산 시작합니다.")
return origin_func(*args, **kwargs) # return 이 중간에 위치함에 따라 아래코드는 실행되지 못한다.
print("계산 완료되었습니다.")
return nested_func
@deco_func
def output(a, b):
return a + b
output(3, 7)
>>> '계산 시작합니다.'
type(output(3,7)) # 값을 반환받았는지 확인해보자.
>>> int
문제점
return
이 코드 중간에 위치함에 따라
return
뒤에 위치한print("계산 완료되었습니다.")
코드는 실행조차 되지않았다.- 결과값 10 이 “계산 시작합니다.” 뒤에 출력되지 않았다.
그러나 결과값 10 은output(3,7)
이 반환받았다.
Step.3
해결해야할 사항 구체화
-
output
함수의 반환값을print("계산 시작합니다.")
와print("계산 완료되었습니다")
코드 사이에서 프린트한다. -
output
함수의 반환값을nested_func
에서 최종적으로 반환시켜야 한다.
def deco_func(origin_func): # 데코레이터 함수
def nested_func(*args, **kwargs):
print("계산 시작합니다.")
print(origin_func(*args, **kwargs)) # 함수 결과값 print 프린트
print("계산 완료되었습니다.")
return origin_func(*args, **kwargs) # 함수 결과값 반환
return nested_func
@deco_func
def output(a, b):
return a + b
이제 결과값을 살펴보자.
output(3,7)
>>> '계산 시작합니다.'
>>> '10'
>>> '계산 완료되었습니다.'
값 반환여부 확인
result = output(3,7)
type(result)
>>> int
print(result)
>>> 10
결과값이 변수에 문제없이 할당된다.
Step. Final
하지만 위의 코드에서는 origin_func
를 두번 실행했다는 점에서 효율적이지 못하다.
따라서 origin func
의 결과값을 변수로 저장한 뒤, print
와 return
을 해주는 방식으로 코드를 개선해보겠다.
def deco_func(origin_func): # 데코레이터 함수
def nested_func(*args, **kwargs):
print("계산 시작합니다.")
result = origin_func(*args, **kwargs) # 함수의 결과값 변수에 할당
print(result) # 결과값 프린트
print("계산 완료되었습니다.")
return result # 결과값 반환
return nested_func
@deco_func
def output(a, b):
return a + b
Leave a comment