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(值)
  • 相关阅读:
    144环形链表
    83. 删除排序链表中的重复元素
    21合并两个有序链表
    PyCharm2020激活破解教程
    Python正课目录
    2条pip命令解决Python项目依赖的导出和导出
    pip离线安装模块
    Python正课149 —— luffy项目 User表的配置
    Python正课148 —— luffy项目 数据库配置
    解决:django中LookupError No installed app with label 'admin'
  • 原文地址:https://www.cnblogs.com/liao-lin/p/7049692.html
Copyright © 2011-2022 走看看