zoukankan      html  css  js  c++  java
  • Python 生成器和协程使用示例

    一、生成器的创建及使用

    生成器比迭代器更节省内存空间,使用生成器,可以生成一个值的序列用于迭代,并且这个值的序列不是一次生成的,而是使用一个,再生成一个,的确可以使程序节省大量的内存损耗

    创建生成器,需带有yield的函数,带有yield关键字的函数,本质上就是一个生成器

    示例:

    # 这是一个生成器对象
    def myYield(n):
    
    	while n > 0:
    		print("开始生成...:")
    		yield n
    		print("完成一次...:")
    		n -= 1
    
    # 实例化一个生成器对象,可以用变量进行直接引用
    my_yield = myYield(3)
    
    print("第一次调用__next()__方法")
    result = my_yield.__next__()
    print("第一次调用后,返回的值是:",result)
    print("第二次调用__next()__方法")
    result = my_yield.__next__()
    print("第二次调用后,返回的值是:",result)
    
    

    输出结果:
    第一次调用__next()__方法
    开始生成...:
    第一次调用后,返回的值是: 3
    第二次调用__next()__方法
    完成一次...:
    开始生成...:
    第二次调用后,返回的值是: 2

    总结:

    • 每次调用__next()__方法,就会生成一次,同时返回n,执行到yield语句后,不会继续往下执行,且结束一次生成
    • 第二次调用__next()__方法,就会从上一次结束执行的地方继续执行,执行到yield语句后,同时返回n,不会继续往下执行

    创建一个能够接收外部参数的生成器,使用send方法向generator生成器进行传值
    示例:

    def myYield(n):
    	while n > 0:
    		rcv = yield n
    		print("接收到外部的值:",rcv)
    		n -= 1
    		if rcv is not None:
    			n = rcv
    if __name__ == "__main__":
    	my_yield = myYield(3)
    	print("第一次调用__next__()的值:")
    	print(my_yield.__next__())
    	print("第二次调用__next__()的值:")
    	print(my_yield.__next__())
    	print("传给生成器一个值,重新初始化生成器。")
    	print("第一次调用__send__()外部传值修改生成器")
    	print(my_yield.send(10))
    	print("第三次调用__next__()的值:")
    	print(my_yield.__next__())
    
    
    
    

    输出结果:
    第一次调用__next__()的值:
    3
    第二次调用__next__()的值:
    接收到外部的值: None
    2
    传给生成器一个值,重新初始化生成器。
    第一次调用__send__()外部传值修改生成器
    接收到外部的值: 10
    10
    第三次调用__next__()的值:
    接收到外部的值: None
    9

    总结:

    1. 调用send()方法向传值,且生成器能正常接收成功,语法:rcv = yield,rcv则是send方法传递过来的值,若无任何参数,返回None
    2. 每次调用send()方法,生成器也会生成一次对应的数值,返回n,且运行到yeild语句后,停止执行
    3. 每次调用一次send(10)方法,传递的值只能被接收到一次,rcv=10,再次调用__next__()方法,rcv=None

    二、协程的介绍

    
    # -*- coding:utf-8 -*-
    
    
    def consumer():
    	print("已经生成一个消费者")
    	while True:
    		print("消费者1号:等待接收处理任务...")
    		data = (yield)
    		print("消费者1号:收到任务:",data,"完成处理...")
    
    
    def producer():
    	c = consumer()
    	c.__next__()
    	for i in range(3):
    		print("生产者1号:发送一个任务...","任务%s" % i)
    		c.send("任务%d" % i)
    
    if __name__ == "__main__":
    	producer()
    
    
    
    

    上述代码输出结果:
    已经生成一个消费者
    消费者1号:等待接收处理任务...
    生产者1号:发送一个任务... 任务0
    消费者1号:收到任务: 任务0 完成处理...
    消费者1号:等待接收处理任务...
    生产者1号:发送一个任务... 任务1
    消费者1号:收到任务: 任务1 完成处理...
    消费者1号:等待接收处理任务...
    生产者1号:发送一个任务... 任务2
    消费者1号:收到任务: 任务2 完成处理...
    消费者1号:等待接收处理任务...

  • 相关阅读:
    记支付宝接口对接,涉及到提取证书SN号的解决方案
    Second Level Cache for Entity Framework 6.1
    记一个dynamic的坑
    使用EntityFramwork[6.1]进行级联保存的时候出现异常
    转:Transform Web.Config when Deploying a Web Application Project
    转:程序员如何增加收入
    超实用的JavaScript技巧及最佳实践(下)
    超实用的JavaScript技巧及最佳实践(上)
    Oracle PL/SQL入门语法点
    轻量级IOC框架:Ninject (下)
  • 原文地址:https://www.cnblogs.com/yangsun/p/11748996.html
Copyright © 2011-2022 走看看