Python 函数高级应用
本文档介绍 Python 函数的高级应用,包括装饰器模式、上下文管理器等高级特性。
1. 装饰器进阶
1.1 带参数的装饰器
import functools
import time
# 带参数的计时装饰器
def timer(prefix=''):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{prefix} 函数 {func.__name__} 执行时间: {end - start:.4f}秒")
return result
return wrapper
return decorator
# 使用示例
@timer(prefix="DEBUG:")
def slow_function():
time.sleep(1)
return "完成"
1.2 多重装饰器
def bold(func):
@functools.wraps(func)
def wrapper():
return f"<b>{func()}</b>"
return wrapper
def italic(func):
@functools.wraps(func)
def wrapper():
return f"<i>{func()}</i>"
return wrapper
@bold
@italic
def hello():
return "Hello, World!"
print(hello()) # 输出: <b><i>Hello, World!</i></b>
1.3 类装饰器
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, url):
self.url = url
print(f"连接到数据库: {url}")
# 使用示例
db1 = Database("localhost:5432")
db2 = Database("localhost:5432")
print(db1 is db2) # 输出: True
1.4 内置装饰器
class Calculator:
# 静态方法装饰器
# 不需要实例即可调用,也不需要传入 self 或 cls 参数
@staticmethod
def add(x, y):
return x + y
# 类方法装饰器
# 第一个参数是类本身,通常命名为 cls
@classmethod
def from_string(cls, expression):
x, op, y = expression.split()
return cls(int(x), int(y))
# 属性装饰器
# 将方法转换为属性
@property
def value(self):
return self._value
# 设置器装饰器
@value.setter
def value(self, new_value):
if new_value < 0:
raise ValueError("Value cannot be negative")
self._value = new_value
# 使用示例
# 静态方法调用
result = Calculator.add(1, 2) # 不需要创建实例
# 类方法调用
calc = Calculator.from_string("1 + 2")
# 属性访问
calc = Calculator()
calc.value = 10 # 使用 setter
print(calc.value) # 使用 getter
这些内置装饰器的主要用途:
-
@staticmethod
- 不需要访问类或实例的方法
- 纯功能性的方法,与类的状态无关
- 可以直接通过类名调用
-
@classmethod
- 需要访问类属性但不需要实例的方法
- 常用于替代构造函数,提供额外的实例化方式
- 第一个参数是类本身(cls)
-
@property
- 将方法转换为只读属性
- 提供对属性的受控访问
- 可以添加验证和计算逻辑
-
@属性名.setter
- 为属性提供设置方法
- 可以在设置值时进行验证
- 与 @property 配合使用
2. 上下文管理器
2.1 基于类的上下文管理器
class FileManager:
def __init__(self, filename, mode='r'):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
if self.file:
self.file.close()
# 返回 True 表示异常已处理
return True
# 使用示例
with FileManager('test.txt', 'w') as f:
f.write('Hello, World!')
2.2 基于生成器的上下文管理器
from contextlib import contextmanager
@contextmanager
def timer_context(name):
start = time.time()
yield
end = time.time()
print(f"{name} 执行时间: {end - start:.4f}秒")
# 使用示例
with timer_context("操作"):
time.sleep(1)
3. 函数缓存
3.1 使用装饰器实现缓存
def memoize(func):
cache = {}
@functools.wraps(func)
def wrapper(*args, **kwargs):
# 创建可哈希的键
key = str(args) + str(sorted(kwargs.items()))
if key not in cache:
cache[key] = func(*args, **kwargs)
return cache[key]
return wrapper
@memoize
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
3.2 使用 lru_cache
from functools import lru_cache
@lru_cache(maxsize=128)
def expensive_function(n):
time.sleep(0.1)
return n * n
# 查看缓存信息
print(expensive_function.cache_info())
4. 函数工厂
4.1 动态创建函数
def create_power_func(power):
def power_func(x):
return x ** power
return power_func
# 创建具体函数
square = create_power_func(2)
cube = create_power_func(3)
print(square(4)) # 输出: 16
print(cube(4)) # 输出: 64
4.2 参数预设
def create_greeting(prefix):
def greeting(name):
return f"{prefix}, {name}!"
return greeting
# 创建特定的问候函数
say_hello = create_greeting("Hello")
say_hi = create_greeting("Hi")
print(say_hello("Alice")) # 输出: Hello, Alice!
print(say_hi("Bob")) # 输出: Hi, Bob!
5. 高级回调模式
5.1 事件处理器
class EventHandler:
def __init__(self):
self._handlers = []
def add_handler(self, handler):
self._handlers.append(handler)
return handler # 允许用作装饰器
def remove_handler(self, handler):
self._handlers.remove(handler)
def fire(self, *args, **kwargs):
for handler in self._handlers:
handler(*args, **kwargs)
# 使用示例
event = EventHandler()
@event.add_handler
def on_event(message):
print(f"处理事件: {message}")
event.fire("Something happened!")
5.2 中间件模式
class MiddlewareManager:
def __init__(self):
self.middlewares = []
def add_middleware(self, middleware):
self.middlewares.append(middleware)
def process(self, data):
def execute(index, current_data):
if index >= len(self.middlewares):
return current_data
return self.middlewares[index](current_data,
lambda d: execute(index + 1, d))
return execute(0, data)
# 使用示例
def logging_middleware(data, next_middleware):
print(f"处理数据: {data}")
result = next_middleware(data)
print(f"处理完成: {result}")
return result
def uppercase_middleware(data, next_middleware):
if isinstance(data, str):
return next_middleware(data.upper())
return next_middleware(data)
manager = MiddlewareManager()
manager.add_middleware(logging_middleware)
manager.add_middleware(uppercase_middleware)
result = manager.process("hello")
6. 函数注解和类型提示
from typing import List, Dict, Optional, Union, Callable
def process_data(
data: List[int],
callback: Callable[[int], int],
config: Optional[Dict[str, str]] = None
) -> Union[List[int], None]:
"""处理数字列表并返回结果"""
if not data:
return None
return [callback(x) for x in data]
# 使用示例
def double(x: int) -> int:
return x * 2
numbers = [1, 2, 3, 4, 5]
result = process_data(numbers, double)
注意事项
- 装饰器会改变函数的元数据,使用
functools.wraps
保留原函数信息 - 缓存装饰器要注意内存使用
- 上下文管理器要确保资源正确释放
- 回调函数要考虑异常处理
- 类型提示主要用于文档和静态检查,不影响运行时行为
最佳实践
- 合理使用装饰器简化代码
- 使用
contextlib
简化上下文管理器的创建 - 适当使用函数缓存提高性能
- 使用类型提示提高代码可读性
- 注意函数的副作用和纯函数设计