实现一个log的decorator,使它既支持:
@log
def f():
pass
也支持:
@log("ERROR")
def f():
pass
实现:
from functools import wraps
def log(ft):
if isinstance(ft, str):
level = ft
def wrapper(func):
@wraps(func)
def inner_wrapper(*args, **kwargs):
print("Log[%s]: call %s()" % (level, func.__name__))
c = func(*args, **kwargs)
print("Log[%s]: end call %s()" % (level, func.__name__))
return c
return inner_wrapper
return wrapper
else:
level = "INFO"
@wraps(ft)
def wrapper(*args, **kwargs):
print("Log[%s]: call %s()" % (level, ft.__name__))
c = ft(*args, **kwargs)
print("Log[%s]: end call %s()" % (level, ft.__name__))
return c
return wrapper
使用log 装饰器装饰方法:
@log
def my_sum(*args):
return sum(*args)
@log("ERROR")
def just_print():
"""just print Hello World string"""
print("Hello World")
n = my_sum(range(0, 10))
print(n)
just_print()
输出:
Log[INFO]: call my_sum()
Log[INFO]: end call my_sum()
45
Log[ERROR]: call just_print()
Hello World
Log[ERROR]: end call just_print()
@wraps()的作用
functools.wraps 则可以将原函数对象的指定属性复制给包装函数对象, 默认有 _module_、_name_, _doc_等
如果打印just_print._name_和 just_print._doc_
print(just_print.__name__)
print(just_print.__doc__)
输出:
just_print
just print Hello World string
如果我们把log装饰器函数里的@wraps()注释删掉,那么则输出:
inner_wrapper
None
网友评论