前言 Python 装饰器是 Python 中非常强大且优雅的特性,理解装饰器对于写出高质量的 Python 代码至关重要。本文将带你从零开始,逐步掌握装饰器的各种用法。
什么是装饰器 装饰器本质上是一个函数,它接受一个函数作为参数,返回一个新的函数。它可以在不修改原函数代码的情况下,给函数增加新的功能。
基础装饰器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def timer(func): """计算函数执行时间的装饰器""" import time def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(f"{func.__name__} 执行耗时: {end - start:.4f}秒") return result return wrapper @timer def slow_function(): import time time.sleep(1) print("函数执行完毕") slow_function() # 输出: 函数执行完毕 # 输出: slow_function 执行耗时: 1.0012秒 带参数的装饰器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 def retry(max_attempts=3, delay=1): """失败自动重试装饰器""" def decorator(func): def wrapper(*args, **kwargs): for attempt in range(max_attempts): try: return func(*args, **kwargs) except Exception as e: if attempt == max_attempts - 1: raise e print(f"第 {attempt + 1} 次失败,{delay}秒后重试...") import time time.sleep(delay) return wrapper return decorator @retry(max_attempts=3, delay=2) def unstable_api_call(): import random if random.random() < 0.7: raise ConnectionError("连接失败") return "请求成功" 使用 functools.wraps 保留元信息 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from functools import wraps def my_decorator(func): @wraps(func) def wrapper(*args, **kwargs): """这是 wrapper 的文档""" print("调用前") result = func(*args, **kwargs) print("调用后") return result return wrapper @my_decorator def greet(name): """打招呼函数""" print(f"你好, {name}!") print(greet.__name__) # greet(而非 wrapper) print(greet.__doc__) # 打招呼函数 类装饰器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Singleton: """单例模式装饰器""" def __init__(self, cls): self._cls = cls self._instance = None def __call__(self, *args, **kwargs): if self._instance is None: self._instance = self._cls(*args, **kwargs) return self._instance @Singleton class Database: def __init__(self): print("数据库连接创建") db1 = Database() # 输出: 数据库连接创建 db2 = Database() # 无输出,返回同一实例 print(db1 is db2) # True 总结 装饰器是 Python 中实现代码复用和功能增强的利器。掌握装饰器后,你会发现很多看似复杂的需求都可以用优雅的方式解决。记住核心原则:装饰器 = 接受函数 + 返回函数。