我认为这里有一个工作的、现实世界的示例,其中包含最通用的用例的使用示例。
下面是函数的装饰器,它在进入和退出函数时输出log。
参数控制是否打印输入输出值,日志级别等。
import logging
from functools import wraps
def log_in_out(logger=logging.get_logger(), is_print_input=True, is_print_output=True, is_method=True, log_level=logging.DEBUG):
"""
@param logger-
@param is_print_input- toggle printing input arguments
@param is_print_output- toggle printing output values
@param is_method- True for methods, False for functions. Makes "self" not printed in case of is_print_input==True
@param log_level-
@returns- a decorator that logs to logger when entering or exiting the decorated function.
Don't uglify your code!
"""
def decor(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
if is_print_input:
logger.log(
msg=f"Entered {fn.__name__} with args={args[1:] if is_method else args}, kwargs={kwargs}",
level=log_level
)
else:
logger.log(
msg=f"Entered {fn.__name__}",
level=log_level
)
result = fn(*args, **kwargs)
if is_print_output and result is not None:
logger.log(
msg=f"Exited {fn.__name__} with result {result}",
level=log_level,
)
else:
logger.log(
msg=f"Exited {fn.__name__}",
level=log_level
)
return result
return wrapper
return decor
用法:
@log_in_out(is_method=False, is_print_input=False)
def foo(a, b=5):
return 3, a
Foo(2)—>打印
输入foo
输出结果为(3,2)的foo
class A():
@log_in_out(is_print_output=False)
def bar(self, c, m, y):
return c, 6
a = ()
A.bar (1,2, y=3)—>打印
输入bar with args=(1, 2), kwargs={y:3}
离开酒吧