Python动态修改装饰器参数:实现超时日志与运行时配置

不晚
不晚
发布时间:2026-10-13 | 6人浏览过
原创

本文详解如何在Python中实现支持动态修改参数的装饰器。通过定义带timeout参数的装饰器,统计函数执行时间并在超时时记录日志。重点讲解利用nonlocal关键字(Python3)或列表索引(Python2)来修改嵌套作用域变量的方法,实现运行时调整超时阈值的功能。

本文分享了Python中修改装饰器参数的具体实现代码,供读者参考学习。

具体案例如下:

为了分析程序中哪些函数的执行耗时较高,我们需要定义一个带有timeout参数的装饰器。

具体需求包括:

统计被装饰函数的实际运行时间。

当运行时间超过设定的timeout值时,将该次函数调用记录到log日志中。

在程序运行过程中,能够动态修改timeout的值。

针对上述需求,解决方案如下:

  • 定义一个装饰器,用于计算函数的执行时间,并与timeout进行比较;若执行时间超过timeout,则通过logging模块打印相应的日志信息。
  • 在包裹函数内部添加一个内部函数,通过该内部函数来修改timeout变量的值。
  • 在Python3中,可以使用nonlocal关键字来声明对嵌套作用域中变量的引用;而在Python2中,可以通过将timeout参数改为列表形式,利用列表索引来修改其值。
#!/usr/bin/python3
 
import time
import logging
from random import randint
 
 
def run_time(timeout):
  """
  定义检查函数运行时间,并打印对应函数运行时间超出设定时间日志,并支持更改timeout
  """
 
  # python2
  # timeout = [timeout]
   
  # 真正包裹函数
  def out_wrapper(func):
    def wrapper(*args, **kwargs):
       
      start_time = time.time()
      result = func(*args, **kwargs)
      used_time = time.time() - start_time
       
      # 对于超出timeout的函数进行日志打印
      if used_time > timeout:
        msg = '%s: %s > %s' % (func.__name__, used_time, timeout)
        logging.warn(msg)
       
      # python2
      # if used_time > timeout[0]:
      #   msg = '%s: %s > %s' % (func.__name__, used_time, timeout[0])
      #   logging.warn(msg)
      # return result
     
    # 设置timeout参数值
    def set_timeout(value):
      nonlocal timeout
      timeout = value
    wrapper.set_timeout = set_timeout
     
    # python2
    # def set_timeout(value):
    #   timeout[0] = value
    # wrapper.set_timeout = set_timeout
     
    return wrapper
  return out_wrapper
 
 
@run_time(1.5)
def func():
  # 随机有50%的几率程序沉睡1秒
  while randint(0, 1):
    time.sleep(1)
  print('func_run')
 
if __name__ == "__main__":
  for _ in range(10):
    func()
     
  print('_'*50)
   
  # 更改run_time装饰器中timeout参数
  func.set_timeout(2)
  for _ in range(10):
    func()

以上就是本文的全部内容,希望能为各位的学习提供帮助,同时也欢迎大家多多支持本站。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表