python高级特性01
装饰器
基本语法
在不改变原函数的基础上,新增/修改一些功能
在被装饰函数/类前使用:@decorator_name
装饰器接收一个函数返回一个新函数
def decorator_name(func):# 装饰器的操作...def wrapper(*args, **kwargs):# 前置操作...result = func()# 后置操作...return resultreturn wrapper@decorator_name
def func():pass
多层装饰器执行顺序
def decorator1(func):def wrapper1(...):func(...)return wrapper1def decorator2(func):def wrapper2(...):func(...)return wrapper2@decorator1
@decorator2
def decorated_func():pass
# 等效于:func = decorator1(decorator2(decorated_func))
由内往外包装:
1、将decorated_func传入decorator2,运行decorator2函数体内容,返回一个新的函数:wrapper2
2、将wrapper2传入decorator1,运行decorator1函数体内容,返回一个新的函数:wrapper1
3、将wrapper1赋值给func
调用func()时,从上往下执行:
1、调用func,即运行decorator1中的wrapper1
2、运行wrapper1中的func时,即运行wrapper2
2、运行wrapper2中的func时,执行decorated_func本身
带参数的装饰器
@main_decorator(params):# 函数体内容...def decorator(func):# 装饰器的操作...def wrapper(*args, **kwargs):# 前置操作...result = func()# 后置操作...return resultreturn wrapperreturn decorator@main_decorator(params)
def func():pass
@decorator_name(params)分为两步:
- 运行main_decorator(params)函数体内容,返回decorator
- 运行@decorator,将func传入decorator,即调用decorator(func)
保留函数元信息
@functools.wraps(func)
@decorator(params):def decorator_name(func):# 装饰器的操作...@functools.wraps(func)def wrapper(*args, **kwargs):# 前置操作...result = func()# 后置操作...return resultreturn wrapper@decorator_name
def func():pass
原理:在wrapper运行前将wrapper的相关属性值修改为func的相关属性值
1、复制原func的方法/函数信息,如__name__ 、__doc__、__dict__等等,保存在类属性中
2、调用被装饰方法时,将被装饰方法传入类的__call__内,将被装饰函数的相关属性赋值给wrapper,再运行
类装饰器
语法同方法/函数装饰器:@classdecorator
通过实现 __call__ 方法使类成为装饰器
普通类装饰器
带参数的类装饰器
应用场景
1、单例模式:确保全局只有一个实例,如数据库连接
2、需要维护复杂状态
3、需要复用多个方法
4、相比函数装饰器更适合复杂场景
元类
基本定义
创建一个继承type的类,其他类应用该元类时,使用metaclass指定元类
class TestMeta(type):def __new__(cls, name, bases, attrs):# 执行操作...return super().__new__(cls, name, bases, attrs)def __init__(cls, name, bases, attrs):# 执行操作...# 注意:__init__无返回值class TestFactory(metaclass=TestMeta):pass
动态创建类
使用 type(name, bases, namespace) 动态生成类
元类的应用场景
单例模式、ORM框架(如Django模型)、接口验证、自动注册子类等。
元类与类装饰器的区别
元类影响类的整个生命周期,类装饰器仅修改已存在的类。
生成器
生成器通过使用yield惰性计算,节省内存
def number_generator():for i in range(1, 10):yield i ** 2ng = number_generator()
print(next(ng))
生成器函数
使用 yield 暂停执行并返回值,下次从暂停处继续执行
生成器表达式
类似列表推导式,但用圆括号:generator = (i**2 for i in range(10))
状态控制
使用 send(value)
向生成器发送值,close()
终止生成器,throw()
抛出异常
协程与异步编程
生成器是协程的基础,yield 可实现简单的协作式多任务。
应用场景
处理大型文件(逐行读取)、无限序列(如斐波那契数列)、流式数据处理。