functools模块
- functools.update_wrapper(wrapper, wrapped, …)
- wrapper 包装函数,被更新者, wrapped, 被包装函数,数据源
- functools.wraps(wrapped…)
源代码:
update_wrapper
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__',
'__annotations__')
WRAPPER_UPDATES = ('__dict__',)
def update_wrapper(wrapper,
wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
for attr in assigned:
try:
value = getattr(wrapped, attr)
except AttributeError:
pass
else:
setattr(wrapper, attr, value)
for attr in updated:
getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
# Issue #17482: set __wrapped__ last so we don't inadvertently copy it
# from the wrapped function when updating __dict__
wrapper.__wrapped__ = wrapped
wraps
def wraps(wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
return partial(update_wrapper, wrapped=wrapped,
assigned=assigned, updated=updated)
简单应用案例
import datetime, time, functools
def copy_properties(fn):
def _copy(wrapper):
wrapper.__name__ = fn.__name__
wrapper.__doc__ = fn.__doc__
return wrapper
return _copy
def x(times, time_,fn):
if times > time_:
print(f"函数{fn}过慢")
else:
print("OK")
def scope(time_=5, fnnc = x):
def logger(fn):
#@copy_properties(fn) # wrapper = copy_properties(fn)(wrapper)
@functools.wraps(fn) # warpper = wraps(fn)(wrapper)
def wrapper(*args, **kwargs):
print("================")
'''python 装饰器'''
date = datetime.datetime.now()
dis = fn(*args, **kwargs)
times = (datetime.datetime.now() - date).total_seconds()
print(times)
fnnc(times, time_, fn)
print("===============")
return dis
# 或者: functools.update_wrapper(wrapper, fn)
return wrapper
return logger
@scope() # add = scope()(add)
def add(x, y):
'''人生苦短,我用python'''
time.sleep(1)
return x + y
print(add(2, 3))
print(add.__name__, add.__doc__)
结果:
================
1.000331
OK
===============
dhcv 5
add 人生苦短,我用python