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装饰器的基础用法和实用示例,希望对你有帮助!

相关推荐
金銀銅鐵3 小时前
[Python] 借助 turtle 逐字展示唐诗《金缕衣》
python
Python大数据分析@5 小时前
使用大模型MCP采集数据,爬虫已经无门槛
python·网络爬虫
quantdash_cc5 小时前
告别自建 Requests/BS4 网页爬虫:基于 QuantDash 搭建零维保的高性能量化行情流水线
开发语言·爬虫·python·pandas·量化·quantdash
65岁退休Coder6 小时前
LangChain v1.3.4 笔记 - 07 补充:链式调用 LCEL
后端·python·langchain
卷无止境6 小时前
FastAPI 部署在 Nginx 后面到底该怎么配
后端·python
半亩码田6 小时前
C#转Python第3.1篇:Python 的 class 没有访问修饰符?面向对象的另一条路
开发语言·python·c#
Wzx1980127 小时前
python沙箱和docker沙箱你选对了吗?
开发语言·python·docker
Python私教7 小时前
签名 URL 刷新导致审批失效?别急着删掉所有 query
python·安全
牧羊人.3337 小时前
Python 办公自动化从入门到入土|09 数据容器之字典
开发语言·python
Zane19947 小时前
类变量与实例变量:一个共享列表引发的线上事故
后端·python