温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何解决使用Python装饰器出现的问题

发布时间:2021-10-26 11:49:19 来源:亿速云 阅读:156 作者:iii 栏目:编程语言

这篇文章主要讲解了“如何解决使用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装饰器出现的问题这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI