# 다음 함수를 함 보자
def logger_login():
print ("Dave login")
logger_login()
# 시간을 앞뒤로 추가하고 싶다.
# 이렇게 넣으면 됩니다.
import datetime
def logger_login():
print (datetime.datetime.now())
print ("Dave login")
print (datetime.datetime.now())
logger_login()
# 아차 다른 비슷한 함수도 다 넣으려면.... 이걸 좀 깔끔하게...
def logger_login_david():
print ("David login")
def logger_login_anthony():
print ("Anthony login")
def logger_login_tina():
print ("Tina login")
# 데코레이터 작성하기
def datetime_decorator(func): # <--- datetime_decorator 는 데코레이터 이름, func 가 이 함수 안에 넣을 함수가 됨
def wrapper(): # <--- 호출할 함수를 감싸는 함수
print ('time ' + str(datetime.datetime.now())) # <--- 함수 앞에서 실행할 내용
func() # <--- 함수
print (datetime.datetime.now()) # <--- 함수 뒤에서 실행할 내용
return wrapper # <--- closure 함수로 만든다.
# 데코레이터 적용하기
@datetime_decorator # @데코레이터
def logger_login_david():
print ("David login")
logger_login_david()
@datetime_decorator # @데코레이터
def logger_login_anthony():
print ("Anthony login")
logger_login_anthony()
@datetime_decorator # @데코레이터
def logger_login_tina():
print ("Tina login")
logger_login_tina()
# decorator 함수 정의
def outer_func(function):
def inner_func():
print('decoration added')
function()
return inner_func
# decorating할 함수
def log_func():
print('logging')
# 본래 함수
log_func()
# log_func 함수에 inner_func 함수의 기능을 추가한 decorated_func 함수
decorated_func = outer_func(log_func)
decorated_func() # <--- 결과는 데코레이터를 사용할 때와 동일함
@outer_func
def log_func():
print('logging')
log_func()
# 데코레이터
def outer_func(function):
def inner_func(digit1, digit2):
if digit2 == 0: # <--- 유효성 검사의 예
print('cannot be divided with zero')
return
return function(digit1, digit2)
return inner_func
# 실제 함수
def divide(digit1, digit2):
return digit1 / digit2
# 데코레이터 사용하기 (유효성 검사)
@outer_func
def divide(digit1, digit2):
return digit1 / digit2
print(divide(4, 2))
print(divide(9, 0))
def type_checker(function):
def inner_func(digit1, digit2):
if (type(digit1) != int) or (type(digit2) != int):
print('only integer support')
return
return function(digit1, digit2)
return inner_func
@type_checker
def muliplexer(digit1, digit2):
return digit1 * digit2
muliplexer(1.1, 2)
# 데코레이터
def type_checker(function):
def inner_func(digit1, digit2):
if (type(digit1) != int) or (type(digit2) != int): # <--- 유효성 검사의 예
print('cannot be divided with zero')
return
return function(digit1, digit2)
return inner_func
# 데코레이터 사용하기 (유효성 검사)
@type_checker
def divide(digit1, digit2):
return digit1 * digit2
divide(0.1, 1)
# 데코레이터 작성하기
def general_decorator(function):
def wrapper(*args, **kwargs):
print('function is decorated')
return function(*args, **kwargs)
return wrapper
# 데코레이터 적용하기
@general_decorator
def calc_square(digit):
return digit * digit
@general_decorator
def calc_plus(digit1, digit2):
return digit1 + digit2
@general_decorator
def calc_quad(digit1, digit2, digit3, digit4):
return digit1 * digit2 * digit3 * digit4
# 함수 호출하기
print (calc_square(2))
print (calc_plus(2, 3))
print (calc_quad(2, 3, 4, 5))
# 여러 데코레이터 작성하기
def decorator1(function):
def wrapper():
print('decorator1')
function()
return wrapper
def decorator2(function):
def wrapper():
print('decorator2')
function()
return wrapper
# 여러 데코레이터를 함수에 한번에 적용하기
@decorator1
@decorator2
def hello():
print('hello')
hello()
def mark_bold(function):
def wrapper(string):
return '<b>' + function(string) + '</b>'
return wrapper
def mark_italic(function):
def wrapper(string):
return '<i>' + function(string) + '</i>'
return wrapper
@mark_bold
def contents(string):
return string
@mark_italic
def contents2(string):
return string
@mark_bold
@mark_italic
def contents3(string):
return string
print (contents('안녕'))
print (contents2('안녕'))
print (contents3('안녕'))
def mark_bold(function):
def wrapper(*args, **kwargs):
return '<b>' + function(*args, **kwargs) + '</b>'
return wrapper
def mark_italic(function):
def wrapper(*args, **kwargs):
return '<i>' + function(*args, **kwargs) + '</i>'
return wrapper
@mark_bold
@mark_italic
def add_html(string):
return string
print (add_html('안녕하세요'))
%%html
<b>안녕</b>
<i>안녕</i>
<b><i>안녕</i></b>
# 데코레이터 작성하기 (for method)
def h1_tag(function):
def func_wrapper(self, *args, **kwargs): # <--- self 를 무조건 첫 파라미터로 넣어야 메서드에 적용가능
return "<h1>{0}</h1>".format(function(self, *args, **kwargs)) # <--- function 함수에도 self 를 넣어야 함
return func_wrapper
# 클래스 선언시 메서드에 데코레이터 적용하기
class Person:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
@h1_tag
def get_name(self):
return self.first_name + ' ' + self.last_name
# 데코레이터 적용 확인해보기
davelee = Person('Lee', 'Dave')
print(davelee.get_name())
print('{} {}'.format(10, 100))
print('{0} {2} {0} {1}'.format(10, 100, 20))
print('{1} {0}'.format(10, 100))
print('{aa} {bb}'.format(aa = 'aaaa', bb = 'cccc'))
# 중첩 함수의 하나 더 깊게 두어 생성
def decorator1(num):
def outer_wrapper(function):
def innter_wrapper(*args, **kwargs):
print('decorator1 {}'.format(num))
return function(*args, **kwargs)
return innter_wrapper
return outer_wrapper
# 위와 같이 작성하면, 다음과 같이 호출할 수 있다.
print_hello = decorator1(1)(print_hello)
print_hello()
# 이를 데코레이터로 표현하면 다음과 같다.
@decorator1(1)
def print_hello():
print('hello')
print_hello()
# 이를 데코레이터로 표현하면 다음과 같다.(이렇게 써도 됨)
@decorator1(num=2)
def print_hello():
print('hello')
print_hello()
def mark_html(tag):
def outer_wrapper(function):
def innter_wrapper(*args, **kwargs):
return '<' + tag + '>' + function(*args, **kwargs) + '</' + tag + '>'
return innter_wrapper
return outer_wrapper
@mark_html('b')
def print_hello():
return 'hello'
print(print_hello())