2019.03.15 TIL
(TIL은 스스로 이해한 것을 바탕으로 정리한 것으로 오류가 있을 수 있습니다)
# 질문에 답하기
- 데코레이터에서 대해 이야기 해보기
데코레이터
데코레이터는 쉽게 기능을 추가할 수 있다.
누가 만들어 놓은 함수를 내가 만들고 있는 함수에 갖다 붙이면
그 기능이 추가되어 버린다.
ex)
from fancy import decofunc
@decofunc
def func(a,b): return a + b
- 이렇게 하면 기능이 그냥 붙어 버림 decofunc의 기능이 실행되고 이후에 def func의 기능이 실행
데코레이터 기본 형태
def outer(org_func): #org_func는 내가 만들고 있는 함수
def inner(*args, **kwargs): # 여기서는 가변인자이고 *과 **을 통해 패킹시킴
print("added functionalty")
return org_func(*args, **kwargs) #실행에서는 *, ** 은 튜플과 딕셔너리로 들어오는 것을 unpacking한다는 것이다.
return inner
def func(a,b):
return a+b
func=outer(func) —–> outer(func)는 return inner가 되고
org_func인자가 func로 됨에 따라서 inner내에서 func가 한번 더 리턴된다.
따라서 여기서 부터 func.name == inner가 된다.
func(10,2)을 실행하면
added functionalty가 되고
리턴값으로 12를 받는다. (inner함수 내부에서 실행)
이것을 나타내기 위해서는 print(func(10,2))가 되어야 한다.
매번 func= outer(func)를 적어줄 수는 없으므로
@outer
def func(a,b):
return a+b # 이것 같이 적어주어도 된다.
overloading , overriding
def f(a,b):
return a+b
def f(a,b):
return a*b
f(2,7) ===> 14
python에서는 덮어씌어지지만 java같은 것은 인자만 다르면 인정해준다. 이를 overloading이라고 한다. 하지만 파이썬에서는 overloading을 인정하지 않는다.
여기서 out 9가 나온것은 실제 출력값이 아니라 함수 내부적으로의 return 값이다.
미션 함수 실행 시간 계산하기
import time
def henchmarker(org_func):
def inner(*args, **kwargs):
start = time.time()
result = org_func(*args, **kwargs)
elapsed = time.time() - start
print(f"elapsed time : {elapsed: .2f}") #{elapsed: .2f}는 무엇일까?
return result
return inner
@henchmarker
def something(a,b):
time.sleep(5) ----> 5초 동안 있다가 실행
return a+b
something(1,2)
미션 callcounter
어떤 함수를 호출한 횟수를 보여준다.
g_call_num = 0
def callcounter(org_func):
def inner(*args, **kwargs):
result = org_func(*args, **kwargs)
global g_call_num
g_call_num += 1
print(f"{g_call_num}번 호출되었습니다.")
return result
return inner
@callcounter
def func(a,b):
return (a+b)
for _ in range(10):
print(func(1,3))
주의사항 만약에 함수를 2개 연속으로 사용할 때
from functools import wraps와 @wraps를 꼭 적어주어야지만
함수가 중복적으로 계산되지 않는다.
하나의 공식으로 알아두자.!!