是一种特殊的迭代器,具备迭代器所有的特性,生成器内部不存储数据,只保存生成数据的计算规则,在
存储大量数据的时候,能够节约内存的开销
在函数中有yeild关键字,返回一个生成器对象
一、生成器和迭代器的区别
生成器属于迭代器的一种,如何区分迭代器和生成器?
1、直接使用判断对象类型是Iterator类型,还是Generator类型。
2、生成器比迭代器多了3个方法
send方法:在生成数据的同时,可以和生成器内部进行数据交互
close: 生成可以调用close方法进行关闭
throw: 可以在生成器内部上一次暂停的yield处引发一个指定的异常类型。生成器内部可以
通过捕获的异常类型来做不同的处
二、创建生成器的两种方式
1、生成器表达式
gen =(i for i in range(10))
2、yeild生成器函数
函数内部只要定义yield这个关键字,那么这个函数就是一个生成器函数
生成器函数调用是不会执行内部代码,而是直接返回一个生成器对象
三、获取生成器数据
next()
g =(i for i in range(10))
print('生成的数据为:', next(g))
四、生成器的内置方法
1、close方法:关闭生成器
2、send方法:生成数据的同时,可以和生成器内部进行数据交互
def work():
print("---------开始执行----------")
val1 = yield 'Start'
print("---------1----------:", val1)
val2 = yield 11
print("---------2----------:", val2)
val3 = yield 22
print("---------3----------:", val3)
val4 = yield 33
print("---------4----------:", val4)
g = work()
print('数据:', next(g))
print('数据:',next(g))
print('数据:',next(g))
r1 = g.send('aa')
print("数据:", r1)
#结果
D:\soft\soft\Python\Python37\python.exe D:/LTT/学习/python/python/01py高阶编程/20220309_生成器&函数进阶/day03/demo3_生成器的send方法.py
---------开始执行----------
数据: Start
---------1----------: None
数据: 11
---------2----------: None
数据: 22
---------3----------: aa
数据: 33
注意:
1、生成器的send方法必须在使用了一次next之后 才能使用
2、send传入的参数,给yeild前面的变量接收
案例1
send传入参数1,生成一个手机号
send传入参数2,生成一个名字
send传入参数3,生成一个邮箱
sned传入其他值,生成包含名字,手机号,邮箱的字典
import faker
# 生成(名字 手机 邮箱)数据的生成器
def work():
fk = faker.Faker(locale='zh_CN')
val = yield 'Start'
while True:
if val == 1:
# 生成手机号
val = yield fk.phone_number()
elif val == 2:
# 生成名字
val = yield fk.name()
elif val == 3:
# 生成邮箱
val = yield fk.email()
else:
# 生成包含名字,手机号,邮箱的字典
val = yield {'name': fk.name(), "mobile": fk.phone_number(), "email": fk.email()}
g = work()
next(g)
print(g.send(1))
print(g.send(2))
print(g.send(3))
print(g.send(4))
#结果
13661479568
黄明
zwan@example.com
{'name': '牟金凤', 'mobile': '13473834763', 'email': 'qinfang@example.org'}
案例2
fixture前置后置的应用
def pest_demo(login_fixure):
print("-----这个是pytest的测试用例-----")
print('测试夹具传递进来的数据', login_fixure)
def login_fixure():
print("用例的前置脚本")
yield 999
print("用例的后置脚本")
if __name__ == '__main__':
# pytest中用例夹具调用的执行过程
g = login_fixure()
res = next(g)
pest_demo(res)
try:
next(g)
except StopIteration:
pass