Decorator là "wrapper" cho phép thực thi code trước/sau hàm được decorate mà không sửa hàm gốc.
Decorator chain
Áp dụng nhiều decorator: thực thi từ dưới lên (bottom-up).
def makebold(fn):
def wrapped():
return "" + fn() + ""
return wrapped
def makeitalic(fn):
def wrapped():
return "" + fn() + ""
return wrapped
@makebold
@makeitalic
def hello():
return "hello world"
print(hello())
Đầu ra
hello world
Thứ tự thực thi
@makeitalicáp dụng trước -> wraphello.@makeboldáp dụng sau -> wrap kết quả của makeitalic.- Gọi
hello(): bold(italic(hello())) -> hello world.
Decorator có tham số
def repeat(n):
def decorator(fn):
def wrapper(*args, **kwargs):
for _ in range(n):
result = fn(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello {name}")
greet("Alice") # In 3 lần
functools.wraps (Best practice)
from functools import wraps
def my_decorator(fn):
@wraps(fn) # Giữ __name__, __doc__, __annotations__ của fn gốc
def wrapper(*args, **kwargs):
return fn(*args, **kwargs)
return wrapper