yield关键字的用法和用途
生成器
来自:https://blog.csdn.net/mieleizhi0522/article/details/82142856/
上下文管理器
配合 Python 的 contexlib
模块里的 @contextmanager
装饰器,yield 也可以用于定义上下文管理器,下面是 Python Tricks 书中的一个例子[3]:
from contextlib import contextmanager @contextmanager def managed_file(name): try: f = open(name, 'w') yield f finally: f.close()
上面通过装饰器和 yield 关键字定义的上下文管理器和下面类的方法定义等同:
class ManagedFile: def __init__(self, name): self.name = name def __enter__(self): self.file = open(self.name, 'w') return self.file def __exit__(self, exc_type, exc_val, exc_tb): if self.file: self.file.close()
可以利用下面的方法分别进行调用:
with ManagedFile('hello.txt') as f: f.write('hello, world!') f.write('bye now') with managed_file('hello.txt') as f: f.write('hello, world!') f.write('bye now')
协程
协程的概念充满了美感,非常符合人的办事模式,想要完全掌握却还是需要花费一些功夫。不过这些功夫是值得的,因为有时多线程所带来的麻烦会远远比协程多。下面是 Python Cookbook 中的一个只用 yield
表达式编写的协程实例[4]:
https://www.zhihu.com/question/345210030/answer/841903171
yield from
yield from
是在Python3.3才出现的语法。所以这个特性在Python2中是没有的。
yield from
后面需要加的是可迭代对象,它可以是普通的可迭代对象,也可以是迭代器,甚至是生成器。
简单应用:拼接可迭代对象#
我们可以用一个使用yield
和一个使用yield from
的例子来对比看下。
使用yield
# 字符串 astr='ABC' # 列表 alist=[1,2,3] # 字典 adict={"name":"wangbm","age":18} # 生成器 agen=(i for i in range(4,8)) def gen(*args, **kw): for item in args: for i in item: yield i new_list=gen(astr, alist, adict, agen) print(list(new_list)) # ['A', 'B', 'C', 1, 2, 3, 'name', 'age', 4, 5, 6, 7]
使用yield from
# 字符串 astr='ABC' # 列表 alist=[1,2,3] # 字典 adict={"name":"wangbm","age":18} # 生成器 agen=(i for i in range(4,8)) def gen(*args, **kw): for item in args: yield from item new_list=gen(astr, alist, adict, agen) print(list(new_list)) # ['A', 'B', 'C', 1, 2, 3, 'name', 'age', 4, 5, 6, 7]
由上面两种方式对比,可以看出,yield from后面加上可迭代对象,他可以把可迭代对象里的每个元素一个一个的yield出来,对比yield来说代码更加简洁,结构更加清晰。
https://www.cnblogs.com/wongbingming/p/9085268.html