Python实现属性可修改的装饰器方式

 更新时间:2024年02月09日 10:02:00   作者:AllardZhao  
这篇文章主要介绍了Python实现属性可修改的装饰器方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

如何实现属性可修改的函数装饰器

实际案例

为分析程序内哪些函数执行时间开销比较大,

我们定义一个带timeout参数的函数装饰器,timeout是一个时间阀值

比如运行时间超过1秒的都是比较慢的,这种函数比较可疑。

装饰器功能如下:

  • 统计被装饰函数单词调用运行时间;
  • 时间大于参数timeout的,将此次函数调用记录到log日志中;
  • 运行时可修改timeout的值(可以动态修改timeout)。

解决方案

为包裹函数增加一个函数作为包裹函数的属性,用来修改闭包中使用的自由变量。

在python3中:使用nonlocal访问嵌套作用域中的变量引用。

代码演示

# _*_ encoding:utf-8 _*_
from functools import wraps
from random import randint
import time
import logging
 
 
# 内部统计一个算法的运行时间
def warn(timeout):
    """ 带参数装饰器也就是内部能返回一个装饰器 """
    # python2中因为没有nonlocal,可以将timeout声明为可变对象
    # timeout = [timeout]
 
    # 装饰器冬季func运行时间
    def decorator(func):
        # 定义包裹函数
        def wrapper(*args, **kwargs):
            start = time.time()
            res = func(*args, **kwargs)
            # 得到运行时间
            used = time.time() - start
            if used > timeout:
                msg = '"%s": %s > %s' % (func.__name__, used, timeout)
                # 如果超时输入到日志当中
                logging.warning(msg)
            # if used > timeout[0]:
            #     msg = '"%s": %s > %s' % (func.__name__, used, timeout[0])
            #     logging.warn(msg)
            # return res
 
        #  动态修改函数属性timeout值
        def set_timeout(k):
            # python3声明嵌套作用域下变量,类似于global
            nonlocal timeout
            timeout = k
            # python2中使用可变对象修改timeout
            # timeout[0] = k
 
        # 将set_timeout函数作为wrapper属性,未来用户就可以通过函数来调用到它。
        wrapper.set_timeout = set_timeout
        return wrapper
 
    return decorator
 
 
# 测试代码
@warn(1.5)
def test():
    print('In test')
    # 随机进入睡眠状态,百分之50概率
    while randint(0, 1):
        time.sleep(0.5)
 
 
for _ in range(30):
    test()
 
# 测试运行时修改timeout属性等于1
test.set_timeout(1)
for _ in range(30):
    test()
 
'''
运行完前30个test函数后修改timeout=1。
运行时可以看到timeout从1.5变成了1,如下:
WARNING:root:"test": 1.509084939956665 > 1.5
WARNING:root:"test": 1.004662036895752 > 1
'''

总结

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

相关文章

  • python+opencv打开摄像头,保存视频、拍照功能的实现方法

    python+opencv打开摄像头,保存视频、拍照功能的实现方法

    今天小编就为大家分享一篇python+opencv打开摄像头,保存视频、拍照功能的实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01
  • python 数字转换为日期的三种实现方法

    python 数字转换为日期的三种实现方法

    在Python中,我们经常需要处理日期和时间,本文主要介绍了python 数字转换为日期的三种实现方法,包含datetime模块,strftime方法及pandas库,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • Python GUI之如何使用tkinter控件

    Python GUI之如何使用tkinter控件

    今天带大家学习Python GUI的相关知识,文中对如何使用tkinter控件作了非常详细的介绍及代码示例,对正在学习python的小伙伴们有很好的帮助,需要的朋友可以参考下
    2021-05-05
  • opencv python 图像轮廓/检测轮廓/绘制轮廓的方法

    opencv python 图像轮廓/检测轮廓/绘制轮廓的方法

    这篇文章主要介绍了opencv python 图像轮廓/检测轮廓/绘制轮廓的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • 一些让Python代码简洁的实用技巧总结

    一些让Python代码简洁的实用技巧总结

    随着项目代码行数的增加,不可避免的遇到软件架构腐败的问题,所以如何写出简洁的代码至关重要,这篇文章主要给大家介绍了一些让Python代码简洁的实用技巧,需要的朋友可以参考下
    2021-08-08
  • Python编程中装饰器的使用示例解析

    Python编程中装饰器的使用示例解析

    这篇文章主要介绍了Python编程中装饰器的使用示例解析,包括装饰函数和方法,含参的装饰器以及装饰类这三个方面,需要的朋友可以参考下
    2016-06-06
  • Python字符串的全排列算法实例详解

    Python字符串的全排列算法实例详解

    这篇文章主要介绍了Python字符串的全排列算法,结合实例形式较为详细的总结分析了Python字符串全排列的常见操作技巧,需要的朋友可以参考下
    2019-01-01
  • python类装饰器用法实例

    python类装饰器用法实例

    这篇文章主要介绍了python类装饰器用法,实例分析了Python类装饰器的相关使用方法,需要的朋友可以参考下
    2015-06-06
  • django缓存配置的几种方法详解

    django缓存配置的几种方法详解

    缓存对各位学习或者使用django的朋友们来说应该都不陌生,下面这篇文章主要给大家介绍了关于django缓存配置的几种方法,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-07-07
  • win7 x64系统中安装Scrapy的方法

    win7 x64系统中安装Scrapy的方法

    这篇文章主要介绍了win7 x64系统中安装Scrapy的方法,图文并茂一步步的教你如何安装Scrapy,需要的朋友可以参考下
    2018-11-11

最新评论