装饰器应用
1,日志
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
查看以上应用代码中使用 了wraps装饰器,接下来我们先认识下wraps装饰器
wraps: 为了使被装饰器装饰后的函数拥有原来的属性, wraps是通过partial和update_wrapper实现的
partial使用:
import functools
def add(a, b):
return a + b
# 通过functools.partial方法创建一个可调用对象new_add
# 此时new_add不是一个函数而是一个可调用对象
# 此时通过partial方法固定了add函数的a参数为1
new_add = functools.partial(add, 1)
result = new_add(3)
# result: 4
展示部分核心partial源码
class partial:
"""New function with partial application of the given arguments
and keywords.
"""
__slots__ = "func", "args", "keywords", "__dict__", "__weakref__"
def __new__(*args, **keywords):
if not args:
raise TypeError("descriptor '__new__' of partial needs an argument")
if len(args) < 2:
raise TypeError("type 'partial' takes at least one argument")
cls, func, *args = args
if not callable(func):
raise TypeError("the first argument must be callable")
args = tuple(args)
if hasattr(func, "func"):
args = func.args + args
tmpkw = func.keywords.copy()
tmpkw.update(keywords)
keywords = tmpkw
del tmpkw
func = func.func
self = super(partial, cls).__new__(cls)
self.func = func
self.args = args
self.keywords = keywords
return self
def __call__(*args, **keywords):
if not args:
raise TypeError("descriptor '__call__' of partial needs an argument")
self, *args = args
newkeywords = self.keywords.copy()
newkeywords.update(keywords)
return self.func(*self.args, *args, **newkeywords)
重写__new__方法自定义创建对象的流程,用来保存被装饰函数和固定参数
wraps源码
def wraps(wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
"""Decorator factory to apply update_wrapper() to a wrapper function
Returns a decorator that invokes update_wrapper() with the decorated
function as the wrapper argument and the arguments to wraps() as the
remaining arguments. Default arguments are as for update_wrapper().
This is a convenience function to simplify applying partial() to
update_wrapper().
"""
return partial(update_wrapper, wrapped=wrapped,
assigned=assigned, updated=updated)
此函数返回partial对象
- 参数
-
wrapped: 被装饰器砖石的原函数
-
assignd: 要被重新赋值的属性列表,默认为WRAPPER_ASSIGNMENTS,可自定义传入
WRAPPER_ASSIGNMENTS = (‘module’, ‘name’, ‘qualname’, ‘doc’,
‘annotations’) -
update: 要被合并的属性列表,默认为WRAPPER_UPDATES,可自定义传入
WRAPPER_UPDATES = (‘dict’,)
-