一个简单的例子
# coding: utf8
from __future__ import print_function
def decorator(func):
def wrap():
print("I am doing some boring work before executing func()")
return func()
print("I am doing some boring work after executing func()")
return wrap
def func():
print("I am the function which needs some decoration to remove my foul smell")
func = decorator(func)
func()
# Output:
# I am doing some boring work before executing func()
# I am the function which needs some decoration to remove my foul smell
# I am doing some boring work after executing func()
解释:
decorator
函数接收一个函数变量func
,内置的wrap
函数对接收到的函数变量func
进行修饰。最后,返回修饰成功的wrap
函数。
使用 Python 的修饰器
# coding: utf8
from __future__ import print_function
def decorator(func):
def wrap():
print("I am doing some boring work before executing func()")
return func()
print("I am doing some boring work after executing func()")
return wrap
@decorator
def func():
print("I am the function which needs some decoration to remove my foul smell")
func()
print(func.__name__)
# Output:
# I am doing some boring work before executing func()
# I am the function which needs some decoration to remove my foul smell
# I am doing some boring work after executing func()
# wrap
解释:
这个和第一个例子其实是一样的,只是更加方便。但这里存在一个问题,func
函数的名字变成了 wrap
。这并不是我们希望看到的。
解决方案
# coding: utf8
from __future__ import print_function
from functools import wraps
def decorator(func):
@wraps(func)
def wrap():
print("I am doing some boring work before executing func()")
func()
print("I am doing some boring work after executing func()")
return wrap
@decorator
def func():
print("I am the function which needs some decoration to remove my foul smell")
func()
print(func.__name__)
# Output:
# I am doing some boring work before executing func()
# I am the function which needs some decoration to remove my foul smell
# I am doing some boring work after executing func()
# func
使用场景1 - 授权
from functools import wraps
def requires_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
auth = request.authorization
if not auth or not check_auth(auth.username, auth.password):
authenticate()
return f(*args, **kwargs)
return decorated
使用场景2 - 日志
from functools import wraps
def logit(func):
@wraps(func)
def with_logging(*args, **kwargs):
print(func.__name__ + " was called")
return func(*args, **kwargs)
return with_logging
@logit
def addition_func(x):
"""Do some math."""
return x + x
result = addition_func(4)
# Output: addition_func was called