Python装饰器入门:让你的代码更优雅

什么是装饰器?

装饰器是Python中一个强大的特性,它允许我们在不修改原函数代码的情况下,给函数添加新的功能。简单来说,装饰器就是一个函数,它接收一个函数作为参数,并返回一个新的函数。

基础示例:计时装饰器

让我们从一个最常用的例子开始------计算函数执行时间:

python 复制代码
import time
from functools import wraps

def timer(func):
    """计算函数执行时间的装饰器"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} 执行时间: {end_time - start_time:.4f}秒")
        return result
    return wrapper

@timer
def slow_function():
    """一个慢函数"""
    time.sleep(1)
    return "完成!"

# 使用
result = slow_function()
# 输出: slow_function 执行时间: 1.0012秒

带参数的装饰器

有时候我们需要给装饰器传递参数,这时需要再包一层:

python 复制代码
def repeat(times=3):
    """重复执行函数的装饰器"""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            results = []
            for _ in range(times):
                result = func(*args, **kwargs)
                results.append(result)
            return results
        return wrapper
    return decorator

@repeat(times=3)
def greet(name):
    return f"你好, {name}!"

# 使用
messages = greet("张三")
print(messages)
# 输出: ['你好, 张三!', '你好, 张三!', '你好, 张三!']

实用装饰器:缓存结果

使用装饰器实现函数结果缓存,提升性能:

python 复制代码
def cache(func):
    """简单的缓存装饰器"""
    cached_results = {}
    
    @wraps(func)
    def wrapper(*args):
        if args in cached_results:
            print(f"从缓存返回: {args}")
            return cached_results[args]
        
        result = func(*args)
        cached_results[args] = result
        return result
    return wrapper

@cache
def fibonacci(n):
    """计算斐波那契数列"""
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

# 使用
print(fibonacci(10))  # 第一次计算
print(fibonacci(10))  # 从缓存返回

类装饰器

装饰器不仅可以是函数,还可以是类:

python 复制代码
class Counter:
    """统计函数调用次数的装饰器"""
    def __init__(self, func):
        self.func = func
        self.count = 0
    
    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"{self.func.__name__} 被调用了 {self.count} 次")
        return self.func(*args, **kwargs)

@Counter
def say_hello():
    print("Hello!")

# 使用
say_hello()  # say_hello 被调用了 1 次
say_hello()  # say_hello 被调用了 2 次
say_hello()  # say_hello 被调用了 3 次

实战:日志装饰器

一个实用的日志装饰器,记录函数调用信息:

python 复制代码
import logging
from datetime import datetime

logging.basicConfig(level=logging.INFO)

def log_calls(func):
    """记录函数调用的装饰器"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        # 记录调用前
        logging.info(f"调用函数: {func.__name__}")
        logging.info(f"参数: args={args}, kwargs={kwargs}")
        logging.info(f"时间: {datetime.now()}")
        
        try:
            result = func(*args, **kwargs)
            logging.info(f"返回值: {result}")
            return result
        except Exception as e:
            logging.error(f"异常: {e}")
            raise
    return wrapper

@log_calls
def divide(a, b):
    """除法函数"""
    return a / b

# 使用
result = divide(10, 2)
# divide(10, 0)  # 会记录异常

总结

装饰器是Python中非常优雅的特性,主要应用场景包括:

  1. 性能监控:计时、内存使用统计
  2. 缓存:避免重复计算
  3. 权限检查:验证用户权限
  4. 日志记录:自动记录函数调用
  5. 重试机制:自动重试失败的操作

掌握装饰器,能让你的Python代码更加优雅和可维护!


本文介绍了Python装饰器的基础用法和实用示例,希望对你有帮助!

相关推荐
吴佳浩2 小时前
LangChain 深入
人工智能·python·langchain
网安-轩逸4 小时前
回归测试原则:确保软件质量的基石
自动化测试·软件测试·python
Mr_Xuhhh5 小时前
YAML相关
开发语言·python
咖啡の猫5 小时前
Python中的变量与数据类型
开发语言·python
汤姆yu5 小时前
基于springboot的电子政务服务管理系统
开发语言·python
执笔论英雄6 小时前
【RL】python协程
java·网络·人工智能·python·设计模式
帮帮志7 小时前
【AI大模型对话】流式输出和非流式输出的定义和区别
开发语言·人工智能·python·大模型·anaconda
jquerybootstrap7 小时前
大地2000转经纬度坐标
linux·开发语言·python
Y***89087 小时前
【JAVA进阶篇教学】第十二篇:Java中ReentrantReadWriteLock锁讲解
java·数据库·python
DanB248 小时前
Java(多线程)
java·开发语言·python