python使用类装饰器生成函数的使用日志

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 在了解类装饰器之前,建议大家先了解装饰器的概念。装饰器知识快速入门链接类装饰器是 Python 中的一种特殊类型的装饰器,它是一个类而不是一个函数。与函数装饰器不同,类装饰器可以在运行时接收参数并返回一个可调用的对象,而不是直接替换被装饰的函数。

1 什么是类装饰器


在了解类装饰器之前,建议大家先了解装饰器的概念。

装饰器知识快速入门链接

类装饰器是 Python 中的一种特殊类型的装饰器,它是一个类而不是一个函数。与函数装饰器不同,类装饰器可以在运行时接收参数并返回一个可调用的对象,而不是直接替换被装饰的函数。


类装饰器的语法是在装饰器类名前面加上 @ 符号,后跟被装饰的函数。它需要实现一个 __init__ 方法来接收被装饰的函数,以及一个 __call__ 方法来替代函数的行为。对于熟悉装饰器的同学来说,类装饰器的__call__其实就是装饰器的内层函数。


类装饰器常用于在运行时动态修改函数的行为,例如记录函数调用日志,缓存函数返回值,检查函数参数等。


2 类装饰器建立流程


定义一个类,该类需要实现一个 init 方法来接收被装饰的函数。


定义一个 call 方法来替代被装饰函数的行为。


使用 @ 符号将类装饰器类名标记在被装饰函数前面。


与装饰器类似,类装饰器的使用方法如下:

@decorator_class
def decorated_function():
    pass


其中 decorator_class 是一个类,它实现了 __init__ 和 __call__ 方法, decorated_function 是被装饰的函数。


在使用类装饰器时需要注意的是,类装饰器的实例是在导入模块时创建的,而不是在调用函数时创建的。这意味着如果类装饰器类中定义了状态,那么所有使用该装饰器的函数将共享该状态。


3 类装饰器示例代码


为了更好的了解类装饰器,我们来看一段包含类装饰器的完整代码。在这个类装饰器中,实现了生成被装饰函数的使用日志这一常用功能。

""""""
类装饰器实现了一个 __call__ 方法来记录函数的使用日志。这个装饰器记录函数运行的开始时间和结束时间,并打印出来。
使用类装饰器时,需要注意的是,类装饰器需要实现一个 __call__ 方法来替代函数的行为。此外,类装饰器需要实现一个 __init__ 方法来接收被装饰的函数。
import datetime
import time
class LoggingDecorator:
    def __init__(self, func):
        self.func = func
    def __call__(self, *args, **kwargs):
        start_time = datetime.datetime.now()
        result = self.func(*args, **kwargs)
        end_time = datetime.datetime.now()
        print(f'{self.func.__name__} ran from {start_time} to {end_time}')
        return result
@LoggingDecorator
def my_function():
    time.sleep(1)
    print('Hello, World!')
my_function()


这段函数的输出如下:

a1c51da4ab1840abb277c58a41d894ca.png


虽然这里我们定义的my_function()函数并没有传参进去,但是类装饰器的__call__方法仍然传入了(*args, **kwargs),这使得我们这个装饰器同样可以作用于带参数的函数。

如果希望将日志保存下来,可以将print函数部分进行替换成如下内容:


with open('log.txt','a',encoding='utf-8') as f:
            f.write(f'{self.func.__name__} ran from {start_time} to {end_time}')


这样,就可以将每次的输出保存在一个文本文件中。

4 原理解释

在定义装饰器的时,等同于以后在执行函数时,将执行

LoggingDecorator(my_function())
1

即将函数传入了装饰器类。

在之后执行my_function()方法(或理解为类方法)时,__call__方法便会被自动执行,因此类装饰器发挥了作用。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
9天前
|
供应链 数据挖掘 Serverless
【python】美妆类商品跨境电商数据分析(源码+课程论文+数据集)【独一无二】
【python】美妆类商品跨境电商数据分析(源码+课程论文+数据集)【独一无二】
【python】美妆类商品跨境电商数据分析(源码+课程论文+数据集)【独一无二】
|
4天前
|
对象存储 Python
Python代码解读-理解-定义一个User类的基本写法
以上描述清晰地阐述了如何在Python中定义 `User`类的基本方法以及如何创建和使用该类的实例。这是面向对象编程中的核心概念,是紧密结合抽象和实现,封装数据并提供操作数据的接口。由于用简单通用的语言易于理解,这样的解释对于初学者而言应该是友好且有帮助的。
13 4
Python 装饰器“高级”使用
本文聚焦两个有意思的点 1. 无参和有参装饰器。 @deco vs @deco(arg1,arg2)。 2. 多层装饰器场景。
|
3天前
|
存储 缓存 算法
Python中的hash函数
Python中的hash函数
|
4天前
|
数据采集 机器学习/深度学习 数据挖掘
如何使用 Python 统计分析 access 日志?
【8月更文挑战第14天】如何使用 Python 统计分析 access 日志?
18 0
如何使用 Python 统计分析 access 日志?
|
6天前
|
Python
Python学习笔记---函数
这篇文章是一份Python函数学习的笔记,涵盖了使用函数的优势、内置函数的调用、自定义函数的定义、函数参数的不同类型(必须参数、关键字参数、默认参数、可变参数)、有返回值和无返回值的函数、形参和实参、变量作用域、返回函数、递归函数、匿名函数、偏函数以及输入和输出函数等多个函数相关的主题。
|
4天前
|
数据采集 监控 Kubernetes
Job类日志采集问题之iLogtail以减小容器发现和开始采集的延时如何优化
Job类日志采集问题之iLogtail以减小容器发现和开始采集的延时如何优化
|
4天前
|
数据采集 Kubernetes Java
Job类日志采集问题之在日志中添加容器的元信息标签,如何操作
Job类日志采集问题之在日志中添加容器的元信息标签,如何操作
|
4天前
|
存储 容器
Job类日志采集问题之DaemonSet采集方式的参数以减小采集延时如何调整
Job类日志采集问题之DaemonSet采集方式的参数以减小采集延时如何调整
|
4天前
|
容器
Job类日志采集问题之ECI产品采集方式对于弹性扩缩容是如何支持的
Job类日志采集问题之ECI产品采集方式对于弹性扩缩容是如何支持的