2023-06-20 02:38:49
生成器函数是一种使用yield关键字实现可暂停、可恢复执行的特殊函数,返回生成器对象以支持惰性求值和高效内存利用。
核心特性与执行机制可暂停与可恢复的执行
生成器函数通过yield语句暂停执行并产出值,下次调用时从暂停处继续。
调用生成器函数时,不会立即执行代码,而是返回生成器对象(迭代器)。
每次调用next()或for循环迭代时,执行到yield暂停并返回值,再次调用时恢复执行。
惰性求值与内存效率
生成器函数仅在需要时计算值,而非预先生成所有结果。
内存占用极低,尤其适合处理超大数据集或无限序列(如流式数据)。
示例:逐行读取大文件时,生成器函数每次仅加载一行,避免内存溢出。
生命周期与状态保存
普通函数遇到return立即终止,销毁局部状态;生成器函数通过yield暂停,保留局部变量和执行位置。
生成器函数可多次产出值,而普通函数通常一次性返回结果。
返回值机制
普通函数返回最终结果(如列表、元组);生成器函数返回生成器对象,通过迭代逐步产出值。
示例:生成斐波那契数列时,普通函数需预先计算全部值,生成器函数则按需生成。
双向通信(send()方法)
通过generator.send(value)向生成器内部传递值,yield表达式接收该值。
示例:实现协程时,外部可控制生成器内部状态(如动态调整参数)。
异常处理(throw()方法)
外部通过generator.throw(exception)向生成器内部抛出异常,内部用try...except捕获。
示例:在生成器处理数据时,外部可强制中断并触发清理逻辑。
资源释放(close()方法)
调用generator.close()终止生成器,抛出GeneratorExit异常,触发finally块释放资源。
示例:关闭文件句柄或网络连接,避免资源泄漏。
生成器表达式
类似列表推导式,但使用圆括号()创建生成器,内存效率更高。
示例:(x*x for x in range(5))生成平方数序列,无需存储全部结果。
普通函数(一次性计算)
def create_list(n): return [i*2 for i in range(n)] # 预先生成全部结果生成器函数(惰性求值)
def generate_numbers(n): for i in range(n): yield i*2 # 按需生成值生成器函数通过yield实现了执行状态的保存与恢复,结合惰性求值和高级控制方法,成为处理大规模数据和构建复杂流程的利器。