함수 내부의 코드를 직접 수정하는 대신 데코레이터를 사용해서 추가적인 처리를 하도록 해주는 디자인 패턴.
파이썬에서의 함수는 일급 객체다. 비행기를 타면 퍼스트 클래스에 탈 수 있다.
def function1():
print("function1")
def function2(f):
f()
function2(function1)
function2
를 호출할 때 function1
을 인수로 넘기고 실행시킬 수 있다.
일급 객체의 특징은 객체
를 변수에 할당하거나, 함수의 인수로 넘기거나, 반환(return)할 수 있다는 것이다.
def function1(function):
def wrapper():
print("1")
function()
print("2")
return wrapper
def hello():
print("hello")
wrapper = function1(hello)
wrapper()
function1
에 hello
객체를 인수로 넘겨주고 wrapper
변수는 wrapper
함수를 할당받는다. 이후 wrapper
를 호출하면 "hello" 전 후로 "1", "2"가 찍힌다
기존 함수명 대신 변수에 할당함으로써 function aliasing을 할 수 있다.
def function1(function):
def wrapper():
print("1")
function()
print("2")
return wrapper
@function1
def hello():
print("hello")
hello()
호출할 함수인 hello
에 데코레이터를 작성해줘도 똑같이 동작한다.
def function1(function):
def wrapper(*args):
print("1")
function(*args)
print("2")
return wrapper
@function1
def hello(n):
print(n)
hello(1.5)
데코레이터가 적용된 함수가 인자를 받아서 사용해야 한다면 래퍼함수에 *args
를 전달해서 사용한다.
def function1(function):
def wrapper(*args, **kwargs):
print("1")
function(*args, **kwargs)
print("2")
return wrapper
@function1
def hello(n, name="hello"):
print(n, name)
hello(1.5)
keyword argument도 전달할 필요가 있다면 **kwargs
를 사용한다.
def function1(function):
def wrapper(*args, **kwargs):
print("1")
v = function(*args, **kwargs)
print("2")
return v
return wrapper
@function1
def hello(x, y):
return x + y
result = hello(1, 9)
print(result)
래퍼함수 내에서 전처리를 하고 후처리하기 전에 값을 v
에 할당하고 마지막에 반환해준다. hello
함수의 데코레이터의 래퍼함수가 반환한 값은 v
가 된다.
import time
def timer(function):
def wrapper():
start = time.time()
function()
end = time.time()
return end - start
return wrapper
@timer
def sleep():
time.sleep(0.1)
slept_time = sleep()
print(slept_time)