Python高级特性深度精讲
Python之所以强大,很大程度上来自这几个高级特性:装饰器、上下文管理器、元类。它们是框架代码和优雅架构的基础,也是从初级到中级的分水岭。
一、装饰器:函数的函数
装饰器的本质是高阶函数,接收一个函数,返回一个新函数。理解它需要先理解Python函数是一等公民。
import time, functools
# 生产级装饰器模板
def retry(max_times=3, delay=1, exceptions=(Exception,)):
"""自动重试装饰器"""
def decorator(func):
@functools.wraps(func) # 保留原函数的__name__,__doc__等
def wrapper(*args, **kwargs):
last_exc = None
for attempt in range(1, max_times + 1):
try:
return func(*args, **kwargs)
except exceptions as e:
last_exc = e
if attempt < max_times:
print(f'{func.__name__} 第{attempt}次失败: {e}, {delay}秒后重试...')
time.sleep(delay)
raise last_exc
return wrapper
return decorator
@retry(max_times=3, delay=2, exceptions=(ConnectionError, TimeoutError))
def call_external_api(url):
import requests
return requests.get(url, timeout=5).json()
二、上下文管理器:优雅处理资源
from contextlib import contextmanager
import sqlite3
# 方式1: 实现__enter__和__exit__
class DatabaseConnection:
def __init__(self, db_path):
self.db_path = db_path
self.conn = None
def __enter__(self):
self.conn = sqlite3.connect(self.db_path)
return self.conn
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type: # 有异常时回滚
self.conn.rollback()
else:
self.conn.commit()
self.conn.close()
return False # 不吞异常
# 方式2: @contextmanager更简洁
@contextmanager
def timer(name):
start = time.time()
yield # yield之前=__enter__, yield之后=__exit__
elapsed = time.time() - start
print(f'{name} 耗时: {elapsed:.3f}s')
# 使用
with DatabaseConnection('app.db') as conn:
conn.execute('INSERT INTO logs VALUES (?)', ('test',))
with timer('数据处理'):
time.sleep(0.5)
三、元类:控制类的创建过程
# 元类的使用场景: ORM框架、API自动注册、单例模式
# 用元类实现单例
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class DatabasePool(metaclass=SingletonMeta):
def __init__(self):
self.pool = []
print('初始化连接池')
p1 = DatabasePool() # 打印: 初始化连接池
p2 = DatabasePool() # 不再打印
print(p1 is p2) # True
# 更实用:用元类自动注册子类
class HandlerRegistry(type):
handlers = {}
def __init__(cls, name, bases, attrs):
super().__init__(name, bases, attrs)
if hasattr(cls, 'event_type'):
HandlerRegistry.handlers[cls.event_type] = cls
class BaseHandler(metaclass=HandlerRegistry): pass
class LoginHandler(BaseHandler):
event_type = 'login'
def handle(self, event): print(f'处理登录事件: {event}')
# 自动查找handler
event = {'type': 'login', 'user': 'alice'}
handler_cls = HandlerRegistry.handlers[event['type']]
handler_cls().handle(event)
四、描述符:property的底层原理
# property的本质是描述符协议
class ValidatedAge:
"""年龄描述符,自动验证范围"""
def __set_name__(self, owner, name):
self.name = name
def __get__(self, obj, objtype=None):
if obj is None:
return self
return obj.__dict__.get(self.name)
def __set__(self, obj, value):
if not isinstance(value, int):
raise TypeError('年龄必须是整数')
if not 0 <= value <= 150:
raise ValueError(f'年龄范围错误: {value}')
obj.__dict__[self.name] = value
class Person:
age = ValidatedAge()
p = Person()
p.age = 25 # OK
p.age = -1 # ValueError!
总结:这三个特性的核心思想都是元编程——用代码控制代码的行为。装饰器在运行时修改函数行为,上下文管理器保证资源正确释放,元类控制类的创建。掌握它们,你能写出更优雅、更有表达力的Python代码。
