这篇文章主要讲解了“如何解决使用Python装饰器出现的问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何解决使用Python装饰器出现的问题”吧!
网站建设哪家好,找创新互联!专注于网页设计、网站建设、微信开发、成都微信小程序、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了连山免费建站欢迎大家使用!
疑问
首先我有一个这样的装饰器文件路径helper/log_helper.py
import traceback from functools import wraps from loguru import logger def my_logger(count): def step1(foo): @wraps(foo) def step2(*args, **kwargs): try: result = foo(*args, **kwargs) logger.info(f"{result=},{count=}") except Exception: logger.exception(traceback.format_exc()) return step2 return step1
然后我有个文件需要引用这个装饰器demo.py
from helper.log_helper import my_logger class Demo: @my_logger(count=2) def main(self): return "in main function" if __name__ == '__main__': d = Demo() d.main()
输出结果如下
2020-10-16 11:43:12.001 | INFO | helper.log_helper:step2:18 - result='in main function',count=2
这个装饰器的作用很简单,就是获取当前函数的返回值,和传入的count值。
好,现在问题来了?
如果给装饰器的参数传值呢,也就是说我的count=2,是通过传值的形式。你想到可能是这样
from helper.log_helper import my_logger COUNT=2 class Demo: @my_logger(count=COUNT) def main(self): return "in main function" if __name__ == '__main__': d = Demo() d.main()
ok,这样确实可以,我们还可以使用再简化一步
from functools import partial from helper.log_helper import my_logger COUNT=2 my_logger = partial(my_logger,count=2) class Demo: @my_logger() def main(self): return "in main function" if __name__ == '__main__': d = Demo() d.main()
暂时来看我们搞定了传参数的问题,这时候我们想如果外界调用了Demo类的main方法,并且向指定count的值怎么办呢?
我们知道外界调用Demo类传参的唯一途径就是向__init__里进行传参数,按照这个思路我们只能这么写了,
class Demo: def __init__(self): count =2 @my_logger(count=self.count) def main(self): return "in main function"
但是这样并不可以,我们得到错误信息
NameError: name 'self' is not defined
在装饰器中无法使用self.形式的参数,难道这个问题解决不了么?
问题解决
在Python3.7之前确实没什么可行的方案。
我们知道在Python3.7的时候引入了dataclasses,我们可以通过它来简化__init__。
改下我们的代码
from functools import partial from helper.log_helper import my_logger from dataclasses import dataclass @dataclass() class Demo: count: int = 2 logger: my_logger = partial(my_logger, count) @logger() def main(self): return "in main function" if __name__ == '__main__': d = Demo() d.main()
如果使用Python3.8那么可以直接忽略掉dataclass
class Demo: count: int = 2 logger: my_logger = partial(my_logger, count) @logger() def main(self): return "in main function"
感谢各位的阅读,以上就是“如何解决使用Python装饰器出现的问题”的内容了,经过本文的学习后,相信大家对如何解决使用Python装饰器出现的问题这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!