zoukankan      html  css  js  c++  java
  • 生成器扩展知识

    生成器扩展知识

    前面说过函数内只要有yield关键字,那么该函数的执行结果就是一个生成器。生成器本身也是一个迭代器对象,可以使用next()方法去取值,还有一个格式可以支持send()去传值给yield并执行next()。

    def foo():
    while True:
        x = yield 'aaa'
        print('value:',x)
    g=foo()
    print(g)
    print(g.send(None))    #第一次必须要next()触发,这里使用send(None)和next(等价)
    print(g.send(2))      #send传值给yield并执行next()
    
    #执行结果:
    <generator object foo at 0x000001D39EC61DB0>
    aaa
    value: 2
    aaa
    

    总结

    • 要使用send方法传值并触发生成器必须至少next()一次,或者send(None)一次,不然会报错:TypeError: can't send non-None value to a just-started generator

    • send(2)的作用就是先执行传值,将2传给yield,然后执行next()

    加装饰器实现先next()一次生成器

    def deco(func):
    	def wrapper(*args,**kwargs):
    		res = func(*args,**kwargs)
    		next(res)
    		return(res)
    	return wrapper
    @deco
    def foo():
    	print('starting ...')
    	while True:
        	x = yield 'aaa'
        	print('value:', x)
    g = foo()
    print(g.send(2))
    
    #执行结果
    starting ...     #g = foo()执行结果
    value: 2
    aaa
    

    与其它函数协同工作

    def deco(func):
    	def wrapper(*args,**kwargs):
    		res = func(*args,**kwargs)
    		next(res)
    		return(res)
    	return wrapper
    list_eat = []
    @deco
    def foo(name):
    	print('starting ...')
    	while True:
        	food = yield list_eat   #yield接受send过来的值,传给food
        	list_eat.append(food)
        	print('%s eat %s' %(name,food))
    
    
    def make_egg(people,num):
    	for i in range(1,num):
        	people.send('egg%s' %i)    #发送给people,peopl必须是一个生成器
    
    g = foo('jack')
    make_egg(g,5)
    
    #执行结果:
    starting ...
    jack eat egg1
    jack eat egg2
    jack eat egg3
    jack eat egg4
    

    多个函数通过生成器协同
    两个函数间传值,接受值格式:

    def deco(func):
    	def wrapper(*args,**kwargs):
        	res = func(*args,**kwargs)
        	next(res)
        	return res
    	return wrapper
    @deco
    def foo1():
    	while True:
    		x1 = yield    #yield接受值,可以是其它函数传值过来
    		print(x1)
    
    def foo2(target):    #target传入foo1
    	target.send(值)
    

    三个或三个以上类似:

    def deco(func):
    	def wrapper(*args,**kwargs):
        	res = func(*args,**kwargs)
        	next(res)
        	return res
    	return wrapper
    @deco
    def foo1():
    	while True:
    		x1 = yield    #yield接受值,可以是其它函数传值过来
    		print(x1)
    
    @deco
    def foo2(target):
    	while True:
    		x2 = yield    
    		target.send(x2)
    def foo3(target):
    	target.send(值)
  • 相关阅读:
    c#的Marshal
    爬虫之requests详解
    爬取抖音视频
    爬取拉钩网
    爬虫自动登陆GitHub
    爬取博客园博客
    爬取煎蛋网文章
    爬取抽屉热搜榜文章
    准备
    爬虫示例
  • 原文地址:https://www.cnblogs.com/liao-lin/p/7049692.html
Copyright © 2011-2022 走看看