python装饰设备,终于解决了使用Python装饰器中的一个痛点,

终于解决了使用Python装饰器中的一个痛点,

前言

如何给装饰器的参数传参,这个问题曾经困扰我好久,虽然Python版本的更新,现在这个问题终于解决了,特此记录。

0Z54GE7-0.jpg-wh_651x-s_2042103016.jpg

疑问

首先我有一个这样的装饰器文件路径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"

这样我们就成功的解决了这个问题,突然想起来之前遇到的这个难题,现在算是解决了,希望对你有帮助。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.m或d论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值