python 网络安全基线报告生成器_python 生成器

生成器(generator)

在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。生成器本身就是迭代器。

1 生成器表达式

生成器表达式的语法和列表生成式的一样,只不过把列表生成式的[]换成()。

gen=(x+y for x in ("A","B","C") for y in ("a","b","c"))

print(gen)

print(next(gen))

print(next(gen))

result:

Aa

Ab

2 生成器函数

在函数中如果出现了yield关键字,那么该函数就不再是普通函数,而是生成器函数。

yield的作用:

yield把函数变成生成器(把__iter__()和__next__()封装到函数里)

yield能让函数挂起,并保存函数当前的运行状态。

yield能返回值(这一点和return类型)

yield和return的区别:

return返回一次值,函数就结束运行。而yield能多次返回值。

有了yield这样灵活的语法,我们就能自己定义生成器了。

from collections import Iterator

def func(n):

i=0

while i<=n:

yield i

i+=2

g=func(10)

if isinstance(g,Iterator):

print(next(g),end=" ")

print(next(g),end=" ")

print(next(g),end=" ")

print(next(g),end=" ")

print(next(g),end=" ")

print(next(g),end=" ")

print(next(g),end=" ")

else:

print(g)

result:

Traceback (most recent call last):

0 2 4 6 8 10 File "D:/devtools/workspace/python/PycharmProjects/py_fulstack_s4/day23/yield用法.py", line 19, in

print(next(g),end=" ")

StopIteration

每次运行遇到yield先执行再挂起,并可以通过next()方法来获取其返回值,然后继续向下运行,直到遇到下一个yield挂起并返回。直到遇到StopIteration停止。

改用for遍历:

if isinstance(g,Iterator):

for i in g:

print(i, end=" ")

else:

print(g)

每一次调用生成器函数返回一个生成器对象,调用同一个生成器函数返回的多个生成器对象互相之间不影响。

def func():

pass

a=func()

b=func()

print(a is b) #True

def generator():

yield 1

g=generator

print(g) #

g1=generator()

print(g1) #

g2=generator()

print(g2) #

print(g1 is g2) #False

g是函数生成器的地址,而g1和g2是生成器对象的地址。可以看出同一个函数生成器调用后赋值给多个变量,这些变量是互不受影响的。

如何接收另一个生成器函数的迭代。通过from关键字来实现

def counter(start=0):

while True:

yield start

start += 1

def gen():

yield 1

yield 2

yield from counter(10)

g=gen()

for i in range(10):

print(next(g),end=" ")

结果:

1 2 10 11 12 13 14 15 16 17

3 生成器常用的方法

close() 关闭生成器,关闭以后再调用next()方法会报出StopIteration。

li=(x for x in range(10) if x%2==0)

print(next(li))

print(next(li))

li.close()

print(next(li))

result:

Traceback (most recent call last):

File "D:/devtools/workspace/python/PycharmProjects/py_fulstack_s4/day23/yield用法.py", line 14, in

print(next(li))

StopIteration

0

2

throws()用来向生成器函数送入一个异常,可以结束系统定义的异常,或者自定义的异常。

throw()后直接抛出异常并结束程序,或者消耗掉一个yield,或者在没有下一个yield的时候直接进行到程序的结尾。

def gen():

while True:

try:

yield "value 1"

yield "value 2"

print("here!")

except ValueError:

print("the ValueError is here")

except TypeError:

break

g=gen()

print(next(g))

print(g.throw(ValueError))

print(next(g))

print(g.throw(TypeError))

result:

value 1

the ValueError is here

Traceback (most recent call last):

value 1

value 2

File "D:/devtools/workspace/python/PycharmProjects/py_fulstack_s4/day23/gen.py", line 18, in

print(g.throw(TypeError))

StopIteration

执行过程:

print(next(g)):输出value 1,并挂起。

由于执行了g.throw(ValueError),所以会跳过所有后续的try语句,也就是说yield ‘value 2’不会被执行,然后进入到except语句,打印出the ValueError is here。然后再次进入到while语句部分,消耗一个yield,所以会输出value 1。

print(next(g)),会执行yield ‘alue 2’语句,并挂起。

g.throw(TypeError):会跳出try语句,从而print(‘here!’)不会被执行,然后执行break语句,跳出while循环,然后到达程序结尾,所以跑出StopIteration异常。

5 yeild在协程中的使用

send()接受外部传入的一个变量,并根据变量内容计算结果后返回接受外部传入的一个变量,并根据变量内容计算结果后返回

def func(name):

print("%s 开始点餐!"%(name))

food_menu=[]

while True:

food=yield food_menu

food_menu.append(food)

print("%s 的菜单是:%s"%(name,food_menu))

print("完成点餐!")

g=func("egg")

print(next(g))

print(g.send("西红柿炒番茄"))

print(g.send("白菜炒包菜"))

result:

egg 开始点餐!

[]

egg 的菜单是:['西红柿炒番茄']

['西红柿炒番茄']

egg 的菜单是:['西红柿炒番茄', '白菜炒包菜']

['西红柿炒番茄', '白菜炒包菜']

g.send(None)或者next(g)可以启动生成器函数并执行到第一个yield语句结束的位置。并执行到第一个yield语句结束的位置。此时food_menu没有值,所以返回为[]。如果去掉next(g),程序会报错TypeError: can't send non-None value to a just-started generator。

当运行代码g.send("西红柿炒番茄"),实际上是把"西红柿炒番茄"赋值给food,而g.send()的返回值就是yield后面跟着的food_menu。输出结果:['西红柿炒番茄']

重复第2步,输出:['西红柿炒番茄', '白菜炒包菜']。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值