Python如何在类中定义装饰器

 更新时间:2024年02月09日 09:58:54   作者:AllardZhao  
这篇文章主要介绍了Python如何在类中定义装饰器的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

如何在类中定义装饰器

实际案例

实现一个能将函数调用信息记录到日志的装饰器:

  • 把每次函数的调用时间,执行时间,调用次数写入日志;
  • 可以对被装饰函数分组,调用信息记录到不同日志;
  • 动态修改参数,比如日志格式;
  • 动态打开关闭日志输出功能。

解决方案

为了让装饰器在使用上更加灵活,我们把类的实例方法作为装饰器

此时在包裹函数中就可以持有实例对象,便于修改属性和拓展功能。

代码演示

# _*_ encoding:utf-8 _*_
import logging
from time import localtime, time, strftime, sleep
from random import choice
 
 
class CallingInfo(object):
 
    # 通过name对为日志分组
    def __init__(self, name):
        log = logging.getLogger(name)
        # 设置log的输出级别
        log.setLevel(logging.INFO)
        # 输入到文件中
        fh = logging.FileHandler(name + '.log')
        log.addHandler(fh)
        log.info('start'.center(50, '-'))
        # 将log变成实例属性
        self.log = log
        # 定义日志的输出格式,函数名、开始时间,执行时间,调用次数
        self.formatter = '%(func)s -> [%(time)s - ' \
                         '%(used)s - %(n_calls)s]'
 
    # 定义装饰器函数
    def info(self, func):
        def wrapper(*args, **kwargs):
            wrapper.n_calls += 1
            lt = localtime()
            start = time()
            res = func(*args, **kwargs)
            used = time() - start
            info = dict()
            info['func'] = func.__name__
            info['time'] = strftime('%x %X', lt)
            info['used'] = used
            info['n_calls'] = wrapper.n_calls
            msg = self.formatter % info
            # 输出日志
            self.log.info(msg)
            return res
 
        # 统计函数调用次数,函数属性类似于函数内的静态变量
        wrapper.n_calls = 0
        return wrapper
 
    # 动态修改formatter参数
    def set_formatter(self, formatter):
        # 修改实例属性
        self.formatter = formatter
 
    # 动态的打开和关闭日志输出,设置level输出级别
    def turn_on(self):
        # INFO级别会输出日志
        self.log.setLevel(logging.INFO)
 
    def turn_off(self):
        # 抬高日志输出级别就会关闭
        self.log.setLevel(logging.WARN)
 
 
# 将f和g输出到一个日志当中,h输出到另一个,需要创建2个实例
# 创建类的实例,使用实例的info方法去装饰函数
c_info1 = CallingInfo('my_log1')
c_info2 = CallingInfo('my_log2')
# 将c_info1日志修改为如下格式
c_info1.set_formatter('%(func)s -> [%(time)s - %(n_calls)s]')
# 关闭c_info2的日志输出
c_info2.turn_off()
 
 
@c_info1.info
def f():
    print('in f')
 
 
@c_info1.info
def g():
    print('in g')
 
 
@c_info2.info
def h():
    print('in h')
 
 
# 测试代码, 循环50次
for _ in range(50):
    # 随机调用上面三个函数中的一个
    choice([f, g, h])()
    # 随机秒数的睡眠
    sleep(choice([0.5, 1, 1.5]))

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Python实现代码统计工具

    Python实现代码统计工具

    这篇文章主要为大家详细介绍了Python实现代码统计工具,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • python3.6使用urllib完成下载的实例

    python3.6使用urllib完成下载的实例

    今天小编就为大家分享一篇python3.6使用urllib完成下载的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • 使用 python pyautogui实现鼠标键盘控制功能

    使用 python pyautogui实现鼠标键盘控制功能

    pyautogui是一个可以控制鼠标和键盘的python库,类似的还有pywin32。这篇文章主要介绍了python中的pyautogui实现鼠标键盘控制功能,需要的朋友可以参考下
    2019-08-08
  • Django重设Admin密码过程解析

    Django重设Admin密码过程解析

    这篇文章主要介绍了Django重设Admin密码过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Python中的hashlib模块解析

    Python中的hashlib模块解析

    这篇文章主要介绍了Python中的hashlib模块解析,hashlib是一个提供字符加密功能的模块,包含MD5和SHA的加密算法,具体支持md5,sha1, sha224, sha256, sha384, sha512等算法, 该模块在用户登录认证方面应用广泛,对文本加密也很常见,需要的朋友可以参考下
    2023-09-09
  • win7 x64系统中安装Scrapy的方法

    win7 x64系统中安装Scrapy的方法

    这篇文章主要介绍了win7 x64系统中安装Scrapy的方法,图文并茂一步步的教你如何安装Scrapy,需要的朋友可以参考下
    2018-11-11
  • JetBrains PyCharm(Community版本)的下载、安装和初步使用图文教程详解

    JetBrains PyCharm(Community版本)的下载、安装和初步使用图文教程详解

    这篇文章主要介绍了JetBrains PyCharm(Community版本)的下载、安装和初步使用教程,本文图文并茂给大家介绍的非常详细,对大家的学习和工作具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2020-03-03
  • 关于Qt6中QtMultimedia多媒体模块的重大改变分析

    关于Qt6中QtMultimedia多媒体模块的重大改变分析

    如果您一直在 Qt 5 中使用 Qt Multimedia,则需要对您的实现进行更改。这篇博文将尝试引导您完成最大的变化,同时查看 API 和内部结构
    2021-09-09
  • 关于数据分析之滚动窗口pandas.DataFrame.rolling方法

    关于数据分析之滚动窗口pandas.DataFrame.rolling方法

    Pandas库中的rolling方法是数据处理中常用的功能,它允许用户对数据进行滚动窗口(滑动窗口)操作,通过指定窗口大小,可以使用不同的聚合函数对窗口内的数据进行计算,例如最大值、最小值、平均值、中位数等,此外,rolling方法还可以计算方差、标准差、偏度、峰度
    2024-09-09
  • Python中偏函数用法示例

    Python中偏函数用法示例

    这篇文章主要介绍了Python中偏函数用法,结合实例形式分析了Python基于functools模块创建和使用偏函数的相关操作技巧与注意事项,需要的朋友可以参考下
    2018-06-06

最新评论