什么是装饰器?
装饰器是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中非常优雅的特性,主要应用场景包括:
- 性能监控:计时、内存使用统计
- 缓存:避免重复计算
- 权限检查:验证用户权限
- 日志记录:自动记录函数调用
- 重试机制:自动重试失败的操作
掌握装饰器,能让你的Python代码更加优雅和可维护!
本文介绍了Python装饰器的基础用法和实用示例,希望对你有帮助!