โจ ์๋ ํ์ธ์, ์ค๋์ Decorator ์ฌ์ฉ๋ฒ์ ๊ฐ๋จํ ์ ๋ฆฌํด๋ณด๋ ค ํฉ๋๋ค.
๐ ๋ง ๊ทธ๋๋ก '๊พธ๋ฉฐ์ฃผ๋' ๊ธฐ๋ฅ์ ํ๋ python callable์
๋๋ค :)
๐คทโโ๏ธ ์ฅ? ๊ทผ๋ฐ callable์ ๋ ๋ญ์ผ?
callable์ ๋ง ๊ทธ๋๋ก 'call ํ ์ ์๋' python ๊ฐ์ฒด๋ฅผ ๋งํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ , 'call'์ด๋ : "()"์ ์ฌ์ฉํ๋ ๊ฒ ์ ๋๋ค. :)
๐ ํจ์, ํน์ class๊ฐ ์ฌ๊ธฐ์ ์ํ์ฃ !
๐ ํจ์๊ฐ์ ๊ฒฝ์ฐ๋, ํจ์ ์ ์์ ๋์์ ๊ฐ๋จํ๊ฒ call ํ ์ ์์ฃ .
def func_call():
print('call!')
# "()"์ ์ฌ์ฉํด call ํ์์ต๋๋ค!
func_call()
>>> call!
๐ ๋ฐ๋ฉด์, class๋ __call__() ํจ์๋ฅผ ์ ์ํด์ฃผ๋ฉด call ํ ์ ์์ต๋๋ค.
class ClassCall(object):
def __init__(self):
pass
def __call__(self):
print('call class!')
instance_call = ClassCall()
instance_call()
>>> call class!
๐ OK! callable์ด ๋ฌด์์ธ์ง ์์์ผ๋, Decorator๋ก ๋์ด๊ฐ๋๋ก ํ์ง์ :)
๐ Decorator๋ '๊พธ๋ฉฐ์ฃผ๋ ์'๋ผ๋ ์๋ฏธ ๊ทธ๋๋ก, callable(ํจ์ or class)๊ฐ call๋ ๋ ์๋ค๋ก ๊พธ๋ฉฐ์ค ์ ์๋ ๊ธฐ๋ฅ์ ๋ํด์ฃผ๋ ๊ฒ์ ๋งํฉ๋๋ค.
๐ ์ฃผ๋ก ๋ฐ๋ณตํ์ฌ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ(์๊ฐ ์ฒดํฌ)๋ค์ ๊ตฌํํ์ฌ ์ฌ์ฉํฉ๋๋ค!
๐ ๋ฐฑ๋ฌธ์ด ๋ถ์ฌ์ผ๊ฒฌ! ํ๋ฒ ๊ฐ๋จํ ์์๋ฅผ ๋ณด์์ฃ :)
import time
# ๋ฐ์ฝ๋ ์ดํฐ ํจ์
def time_check(func):
def deco_wrapper():
print(func.__name__, 'function start')
st = time.time()
func()
et = time.time()
print("Function Spent TIME : {}".format(et-st))
print(func.__name__, 'function end')
return deco_wrapper
@time_check
def print_yaho():
print('yaho!')
print_yaho()
>>> print_yaho function start
yaho!
Function Spent TIME : 4.291534423828125e-06
print_yaho function end
def print_yaho():
print('yaho!')
print_yaho()
>>> yaho!
๐ ์์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ๋ง๋ค์ด, ํจ์ ์ ์ธ์ "@"๋ก ๊พธ๋ฉฐ์ฃผ๋ฉด
โ deco_wrapper์์ ๋ก์ง์ด ์๋ค๋ก ์ํ๋ ํ func, ์ฆ printyaho๊ฐ ์ํ๋๋ ๊ฒ์ ๋ณด์ค ์ ์์ต๋๋ค :)
๐ ํจ์ ์ํ์๊ฐ ์ฒดํฌ์ ์์ฃผ ์ ์ฉํ๊ฒ ์ฃ ? ๐
๐ ์ข ๋ ๋์๊ฐ Decorator์ ์ธ์๋ ์ค ์ ์๊ณ , ์ค์ ํ๋ก๋์
์์ ์ฌ์ฉํ๋ ค๋ฉด ๋ช๊ฐ์ง ์กฐ์น๋ฅผ ์ข ๋ ์ทจํด์ฃผ์ด์ผ ํฉ๋๋ค.
๐ค ์ฌ๋ฌ๊ฐ์ Decorator๊ฐ ํ๋์ ํจ์์ ์ ์ฉ๋๋ค๋ฉด, ํจ์๋ช
์ด ์ ๋๋ก ์ถ๋ ฅ๋์ง ์๊ธฐ ๋๋ฌธ์ด์ง์!
์์ธํ ๋ด์ฉ์ https://dojang.io/mod/page/view.php?id=2429 ๋ฅผ ์ฐธ๊ณ ํ์์ต๋๋ค :)
๐ ์ฆ, Decorator์ ์ธ์๋ฅผ ์ฃผ๊ณ , ๊ฐ๋ณ์ธ์๊น์ง ์ฌ์ฉํ ์ต์ข ํ ํ๋ฆฟ์ ๋๋ต ์๋์ ๊ฐ์ต๋๋ค.
import functools
def time_check(decimal):
def decorator_time_check(func):
@functools.wraps(func)
def wrapper_time_check(*args, **kwargs):
st = time.perf_counter()
print('HERE IS {}`s TIME CHECK START!'.format(func.__name__))
value = func(*args, **kwargs)
et = time.perf_counter()
print('HERE IS {}`s TIME! : {}'.format(func.__name__, round(et-st, decimal)))
return value
return wrapper_time_check
return decorator_time_check
@time_check(decimal=12)
def calc_repeat(rep=10**6):
sum = 0
for i in range(rep):
sum += i
return sum
calc_repeat()
๐ ์ํ ์๊ฐ์ ์์ซ์ ๋ช์๋ฆฌ๊น์ง ๋ฃ์ ๊ฒ์ธ์ง์ ๋ํ decorator ๋ณ์ 'decimal'์ ์ถ๊ฐํ์ผ๋ฉฐ,
๐ func์ ์ธ์๋ฅผ ๊ฐ๋ณ ์ธ์ ์ฒ๋ฆฌํ์ฌ, ์ด๋ค ํจ์๊ฐ ์ค๋๋ผ๋ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๊ฒ ๊ตฌํํ์์ต๋๋ค.
๐ ์ด์ฐ๋์๊ฑด, Decorator๋ ์ผ์ข
์ ํ
ํ๋ฆฟ ๊ฐ์ ๋๋์ด๊ธฐ์, ์๋ ๊ฒ ๊ตฌํํด๋๊ณ ์ ๋ ๊ทธ๋ฅ ๊ฐ์ ธ๋ค ์ฐ๋ ํธ์
๋๋ค :)
๐ ์ค๋์ ๊ฐ๋ตํ Decorator์ ๋ํด ์ ๋ฆฌํด ๋ณด์์ต๋๋ค.
๐ ๋จ์ํ ์ํ ์๊ฐ ์ธก์ ์ด์ธ์๋ ๋ค์ํ๊ฒ ์ฌ์ฉ๋ ์ ์๋ Decorator!
๐ ์ ์์๋๋ฉด ๋ณต์กํด๋ณด์ด๋ ์คํ์์ค ์ฝ๋๋ฅผ ๋ค์ ๊ฑฐ๋ฆด๋๋ ํฐ ๋์์ด ๋ฉ๋๋ค :)
๐ค ๊ทธ๋ผ, ์ฝ์ด์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค. ์ข์ ํ๋ฃจ ๋์ธ์!