[解决方案1]:
简短的回答是否定的,但是你可以修改装饰器函数的代码;例如:
def decorator(func):
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner
这是一个标准的装饰器函数,我们稍作修改。
你可以这样做:
def decorator(func,defaultdescription,defaultnum):
def inner(description=defaultdescription,num=defaultnum,*args,**kwargs):
print("function",func.__code__.co_name,"with description",description,"with number",num)
return func(*args,**kwargs)
return inner
所以你可以更改函数的描述
【讨论】:
[解决方案2]:
基本上,装饰器是内部的另一个函数,它在完成时调用您的函数。如果您打算使用自己的装饰器,则必须有一个内部函数来执行所需的任务并调用使用装饰器函数的函数。你可以使用 *args 和 **kwargs
以下代码是python装饰器的基本实现
# Python code to illustrate
# Decorators basic in Python
def decorator_fun(func):
def inner(*args, **kwargs):
"""
do your actual task here
"""
for argv in args:
print(argv)
for key in kwargs:
print(key)
#returning to function which used the decorator at last
func()
return inner
@decorator_fun
def func_to():
print("Inside actual function")
func_to("hello",{"test": "value 1"})
【讨论】:
[解决方案3]:
正如其他人在这里所写,装饰器是函数的语法糖(即,使程序更易于阅读、编写或理解),它将另一个函数作为参数并从内部激活它。
所以,用装饰器调用这个“Add()”函数,如下所示:
@wrapper()
def Add(x: int, y: int):
return x + y
这就像使用“Add”函数作为变量调用“wrapper”函数一样。像这样:
wrapper(Add)(x,y) # pass x,y to wrapper that pass it to Add function.
因此(我发现)向装饰器添加参数的最佳方法是将其全部嵌套在另一个包含子装饰器的函数下。例如:
@deco_maker(msg: str)
def Add(x: int, y: int):
return x + y
看起来像这样:
deco_maker(msg)(wrapper(Add))(x,y)
所以,这是一个简单的包装装饰器,它记录一个没有参数的函数调用,如下所示:
def wrapper(func: Callable):
def wrapper_func(*args, **kwargs):
logging.DEBUG f"Function '{func.__name__}' called with args: {[str(arg) for arg in args]}."
value = func(*args, **kwargs)
return value
return wrapper_func
这里是带有相关日志记录参数的扩展装饰器(日志名称和级别以获得更大的灵活性):
def log_func_calls(logger_name: str, log_level: int):
def wrapper(func: Callable):
def wrapper_func(*args, **kwargs):
logger = logging.getLogger(logger_name)
logger.log(
level=log_level,
msg=f"Function '{func.__name__}' called with args: {[str(arg) for arg in args]}."
)
value = func(*args, **kwargs)
return value
return wrapper_func
return wrapper
这是一个参数化装饰器的完整代码示例,它记录一个函数调用并在它之后打印日志文件输出。
例子:
import logging
from typing import Callable
# define app logger with file and console handlers
def setup_logging():
logger = logging.getLogger('test_app')
logger.setLevel(logging.DEBUG)
# create file handler which logs even debug messages
fh = logging.FileHandler('test.log')
fh.setLevel(logging.DEBUG)
# create formatter and add it to the file handler
formatter = logging.Formatter('{asctime} | {name} | {levelname:^8s} | {message}', style='{')
fh.setFormatter(formatter)
# add the handler to the logger
logger.addHandler(fh)
return logger
# define a log decorator to trace function calls
def log_func_calls(logger_name: str, log_level: int):
def wrapper(func: Callable):
def wrapper_func(*args, **kwargs):
logger = logging.getLogger(logger_name)
logger.log(
level=log_level,
msg=f"Function '{func.__name__}' called with args: {[str(arg) for arg in args]}."
)
value = func(*args, **kwargs)
return value
return wrapper_func
return wrapper
# sample usage 1
@log_func_calls(logger_name='test_app', log_level=logging.DEBUG)
def Add(x: int, y: int):
return x + y
# sample usage 2
@log_func_calls(logger_name='test_app', log_level=logging.DEBUG)
def Sub(x: int, y: int):
return x - y
# a test run
def main():
logger = setup_logging()
logger.info("<<>>")
print(Add(50,7))
print(Sub(10,7))
print(Add(50,70))
logger.info("<<>>")
if __name__ == "__main__":
main()
还有日志输出:
...
2022-06-19 23:34:52,656 | test_app | DEBUG | Function 'Add' called with args: ['50', '7'].
2022-06-19 23:34:52,656 | test_app | DEBUG | Function 'Sub' called with args: ['10', '7'].
2022-06-19 23:34:52,657 | test_app | DEBUG | Function 'Add' called with args: ['50', '70'].
...
【讨论】:
© 版权声明
本站下载的源码均来自公开网络收集转发二次开发而来,
若侵犯了您的合法权益,请来信通知我们1413333033@qq.com,
我们会及时删除,给您带来的不便,我们深表歉意。
下载用户仅供学习交流,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担,访问及下载者下载默认同意本站声明的免责申明,请合理使用切勿商用。
THE END
暂无评论内容