python @mylog.timer 装饰器的使用

 更新时间:2026年03月22日 10:08:26   作者:Yorlen_Zhang  
本文详细介绍了Python计时装饰器@mylog.timer的实现与应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

@mylog.timer 装饰器的详细教学。这通常是指用于测量函数执行时间并记录日志的装饰器

1. 基础版本:简易计时装饰器

import time
import functools

def timer(func):
    """基础计时装饰器"""
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.perf_counter()
        result = func(*args, **kwargs)
        end_time = time.perf_counter()
        print(f"[TIMER] {func.__name__} 执行时间: {end_time - start_time:.4f} 秒")
        return result
    return wrapper

# 使用方式
@timer
def slow_function():
    time.sleep(1)
    return "完成"

slow_function()
# 输出: [TIMER] slow_function 执行时间: 1.0023 秒

2. 进阶版本:集成日志系统(推荐)

实际项目中,我们通常需要专业的日志管理:

import logging
import time
import functools
from typing import Callable, Any
# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)
class MyLog:
    """日志工具类,包含计时装饰器"""
    def __init__(self, name: str = "MyLog"):
        self.logger = logging.getLogger(name)
    def timer(self, level: int = logging.INFO):
        """
        带日志级别的计时装饰器
        用法:
        @mylog.timer()
        @mylog.timer(logging.DEBUG)
        """
        def decorator(func: Callable) -> Callable:
            @functools.wraps(func)
            def wrapper(*args, **kwargs) -> Any:
                # 记录开始时间
                start_time = time.perf_counter()
                try:
                    # 执行函数
                    result = func(*args, **kwargs)
                    # 计算耗时
                    end_time = time.perf_counter()
                    duration = end_time - start_time
                    # 获取函数参数信息
                    args_repr = [repr(a) for a in args]
                    kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()]
                    signature = ", ".join(args_repr + kwargs_repr)
                    # 记录日志
                    self.logger.log(
                        level,
                        f"[TIMER] {func.__name__}({signature}) -> {duration:.4f}s"
                    )
                    return result
                except Exception as e:
                    # 异常时也记录耗时
                    end_time = time.perf_counter()
                    duration = end_time - start_time
                    self.logger.error(
                        f"[TIMER] {func.__name__} 执行失败,耗时: {duration:.4f}s, 错误: {e}"
                    )
                    raise
            return wrapper
        return decorator
# 实例化
mylog = MyLog()
# 使用示例
@mylog.timer()
def calculate_sum(n: int):
    """计算 1 到 n 的和"""
    return sum(range(1, n + 1))
@mylog.timer(logging.DEBUG)
def fetch_data(url: str):
    """模拟获取数据"""
    time.sleep(0.5)
    return f"Data from {url}"
# 测试
calculate_sum(1000000)
fetch_data("https://api.example.com")

3. 高级版本:带配置和统计功能

import logging
import time
import functools
import statistics
from typing import Dict, List
from collections import defaultdict

class AdvancedMyLog:
    """高级日志类,支持统计多次调用的性能数据"""
    
    _stats: Dict[str, List[float]] = defaultdict(list)
    
    def __init__(self, name: str = "AdvancedLog"):
        self.logger = logging.getLogger(name)
        handler = logging.StreamHandler()
        formatter = logging.Formatter(
            '%(asctime)s | %(name)s | %(levelname)s | %(message)s'
        )
        handler.setFormatter(formatter)
        self.logger.addHandler(handler)
        self.logger.setLevel(logging.DEBUG)
    
    def timer(self, log_args: bool = True, alert_threshold: float = None):
        """
        高级计时装饰器
        
        Args:
            log_args: 是否记录函数参数
            alert_threshold: 超时警告阈值(秒)
        """
        def decorator(func):
            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                func_name = func.__qualname__
                start = time.perf_counter()
                
                result = func(*args, **kwargs)
                
                duration = time.perf_counter() - start
                
                # 保存统计数据
                self._stats[func_name].append(duration)
                
                # 构建日志消息
                if log_args and (args or kwargs):
                    args_str = ", ".join(
                        [repr(a) for a in args[1:]] +  # 排除 self/cls
                        [f"{k}={v!r}" for k, v in kwargs.items()]
                    )
                    msg = f"[TIMER] {func_name}({args_str}) 耗时: {duration:.4f}s"
                else:
                    msg = f"[TIMER] {func_name} 耗时: {duration:.4f}s"
                
                # 检查阈值
                if alert_threshold and duration > alert_threshold:
                    self.logger.warning(f"[SLOW] {msg} (超过阈值 {alert_threshold}s)")
                else:
                    self.logger.info(msg)
                
                return result
            return wrapper
        return decorator
    
    @classmethod
    def get_stats(cls, func_name: str = None):
        """获取性能统计报告"""
        if func_name:
            times = cls._stats.get(func_name, [])
            if not times:
                return f"{func_name}: 无数据"
            return {
                "函数": func_name,
                "调用次数": len(times),
                "平均耗时": statistics.mean(times),
                "最大耗时": max(times),
                "最小耗时": min(times),
            }
        
        return {name: cls.get_stats(name) for name in cls._stats}

# 使用示例
adv_log = AdvancedMyLog()

class DataProcessor:
    @adv_log.timer(alert_threshold=1.0)  # 超过1秒警告
    def process(self, data: list):
        time.sleep(0.8)  # 模拟处理
        return len(data)

processor = DataProcessor()
processor.process([1, 2, 3])
processor.process([4, 5, 6])

# 查看统计
print(AdvancedMyLog.get_stats("DataProcessor.process"))

4. 异步函数支持

现代 Python 常使用 async/await,需要特殊处理:

import asyncio
import time
import functools

class AsyncTimerLog:
    def __init__(self):
        self.logger = logging.getLogger("AsyncLog")
    
    def timer(self, func):
        """支持异步函数的计时装饰器"""
        @functools.wraps(func)
        async def async_wrapper(*args, **kwargs):
            start = time.perf_counter()
            result = await func(*args, **kwargs)
            duration = time.perf_counter() - start
            self.logger.info(f"[ASYNC TIMER] {func.__name__} 耗时: {duration:.4f}s")
            return result
        
        @functools.wraps(func)
        def sync_wrapper(*args, **kwargs):
            start = time.perf_counter()
            result = func(*args, **kwargs)
            duration = time.perf_counter() - start
            self.logger.info(f"[SYNC TIMER] {func.__name__} 耗时: {duration:.4f}s")
            return result
        
        # 自动判断是否是协程函数
        if asyncio.iscoroutinefunction(func):
            return async_wrapper
        return sync_wrapper

# 使用
mylog = AsyncTimerLog()

@mylog.timer
async def async_fetch():
    await asyncio.sleep(1)
    return "data"

@mylog.timer
def sync_fetch():
    time.sleep(0.5)
    return "data"

# 运行
sync_fetch()
asyncio.run(async_fetch())

5. 使用场景与最佳实践

5.1 性能监控

# 监控 API 接口响应时间
@mylog.timer(alert_threshold=2.0)
def api_endpoint():
    # 数据库查询等操作
    pass

5.2 算法优化对比

@mylog.timer()
def algorithm_v1(data):
    # 旧算法
    pass

@mylog.timer()
def algorithm_v2(data):
    # 新算法
    pass

# 对比两者的执行时间

5.3 上下文管理器(替代方案)

import time
from contextlib import contextmanager

@contextmanager
def timer_context(name: str):
    start = time.perf_counter()
    yield
    duration = time.perf_counter() - start
    print(f"[BLOCK TIMER] {name}: {duration:.4f}s")

# 使用
with timer_context("代码块 A"):
    time.sleep(1)

6. 注意事项

注意点说明
functools.wraps必须保留原函数的元数据(__name____doc__
异常处理确保即使函数抛出异常也能记录耗时
性能开销日志本身有开销,生产环境建议设置开关
线程安全多线程环境下统计数据需要加锁

完整使用模板

# config.py 或 utils.py
import logging
import time
import functools

class MyLog:
    _instance = None
    
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self, name="MyApp"):
        if not hasattr(self, 'logger'):
            self.logger = logging.getLogger(name)
            self.logger.setLevel(logging.INFO)
            if not self.logger.handlers:
                handler = logging.StreamHandler()
                handler.setFormatter(
                    logging.Formatter('%(asctime)s - %(message)s')
                )
                self.logger.addHandler(handler)
    
    def timer(self, level=logging.INFO):
        def decorator(func):
            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                start = time.perf_counter()
                try:
                    result = func(*args, **kwargs)
                    duration = time.perf_counter() - start
                    self.logger.log(
                        level, 
                        f"[⏱️ TIMER] {func.__name__} completed in {duration:.4f}s"
                    )
                    return result
                except Exception as e:
                    duration = time.perf_counter() - start
                    self.logger.error(
                        f"[⏱️ TIMER] {func.__name__} failed after {duration:.4f}s: {e}"
                    )
                    raise
            return wrapper
        return decorator

# 全局实例
mylog = MyLog()

# 业务代码中使用
@mylog.timer()
def your_function():
    pass

到此这篇关于python @mylog.timer 装饰器的使用的文章就介绍到这了,更多相关python @mylog.timer 装饰器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • php memcached的实例用法详解

    php memcached的实例用法详解

    在本篇文章里小编给大家整理了一篇关于php memcached的实例用法内容,有兴趣的朋友们可以跟着学习参考下。
    2021-10-10
  • Python基于OCR实现图片识别翻译工具功能(附源码)

    Python基于OCR实现图片识别翻译工具功能(附源码)

    这篇文章主要为大家详细介绍了Python如何通过智能OCR文字识别和精准翻译技术,实现一键截图翻译,大幅提升跨语言阅读效率,让语言不再成为信息获取的障碍,感兴趣的可以了解下
    2025-11-11
  • 对tf.reduce_sum tensorflow维度上的操作详解

    对tf.reduce_sum tensorflow维度上的操作详解

    今天小编就为大家分享一篇对tf.reduce_sum tensorflow维度上的操作详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • 浅谈python3.x pool.map()方法的实质

    浅谈python3.x pool.map()方法的实质

    这篇文章主要介绍了python3.x pool.map方法的实质,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • python assert的用处示例详解

    python assert的用处示例详解

    python assert 句语格式及用法很简单。通常程序在运行完之后抛出异常,使用assert可以在出现有异常的代码处直接终止运行。这篇文章通过实例代码介绍了python assert的用处 ,需要的朋友可以参考下
    2019-04-04
  • Python挑选文件夹里宽大于300图片的方法

    Python挑选文件夹里宽大于300图片的方法

    这篇文章主要介绍了Python挑选文件夹里宽大于300图片的方法,实例分析了Python中PIL库的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • python Hypothesis生成和执行大量的测试用例

    python Hypothesis生成和执行大量的测试用例

    Hypothesis是一个基于属性的测试(property-based testing)库,它能够帮助我们生成和执行大量的测试用例,与传统的单元测试相比,属性测试更加灵活和全面,能够发现更多的边界情况和潜在的错误
    2024-01-01
  • Python实现更改图片尺寸大小的方法(基于Pillow包)

    Python实现更改图片尺寸大小的方法(基于Pillow包)

    这篇文章主要介绍了Python实现更改图片尺寸大小的方法,结合实例形式分析了Python基于Pillow包更改图片属性的相关技巧,需要的朋友可以参考下
    2016-09-09
  • 使用Python为中秋节绘制一块美味的月饼

    使用Python为中秋节绘制一块美味的月饼

    这篇文章主要介绍了使用Python为中秋节绘制一块美味的月饼,,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • Django框架静态文件使用/中间件/禁用ip功能实例详解

    Django框架静态文件使用/中间件/禁用ip功能实例详解

    这篇文章主要介绍了Django框架静态文件使用/中间件/禁用ip功能,结合实例形式详细分析了Django框架静态文件的使用、中间件的原理、操作方法以及禁用ip功能相关实现技巧,需要的朋友可以参考下
    2019-07-07

最新评论