python 协程中的迭代器,生成器原理及应用实例详解


Posted in Python onOctober 28, 2019

本文实例讲述了python 协程中的迭代器,生成器原理及应用。分享给大家供大家参考,具体如下:

1.迭代器理解

迭代器:

  • 迭代器是访问可迭代对象的工具

  • 迭代器是指用iter(obj)函数返回的对象(实例)

  • 迭代器是指用next(it)函数获取可迭代对象的数据

迭代器函数(iter和next)

  • iter(iterable)从可迭代对象中返回一个迭代器,iterable必须是能提供一个迭代器的对象

  • next(iterator) 从迭代器iterator中获取下一了记录,如果无法获取下一条记录,则触发stoptrerator异常

说明:
1.迭代器只能往前取值,不会后退
2.用iter函数可以返回一个可迭代对象的迭代器

2.迭代器的应用

class Fabonacci(object):
  def __init__(self,all_num):
    self.all_num = all_num
    self.current_num = 0
    self.a = 0
    self.b = 1


  def __iter__(self):
    return self


  def __next__(self):
    if self.current_num < self.all_num:
      ret = self.a

      self.a, self.b = self.b, self.a + self.b
      self.current_num += 1

      return ret
    else:
      raise StopIteration


fibo = Fabonacci(10)
for num in fibo:
  print(num)

python 协程中的迭代器,生成器原理及应用实例详解

3.生成器的理解

生成器(generator)

  • 是构造新的可迭代对象的一种简单方式。一般的函数return只会返回单个值,而生成器并不是直接将可迭代值直接放入内存中,而是以延迟的方式返回一个值序列,即每返回一个值之后暂停,直到下一个值被请求时再继续,可有效节省内存占用。

  • 要构建一个生成器,则需要用到关键字yield,yield的作用与函数的返回值return有些类似,通过在函数中将return替换成yield就是把函数变成生成器,带有
    yield 的函数不再是普通函数,python
    解释器会将函数对象视为生成器对象,并且该生成器返回的是yield表达式生成的可迭代值序列,可通过for循环等方法依次读取生成器返回的可迭代值序列

  • 生成器生成的可迭代值只可以被读取一次,每一次迭代都是按生成器代码流程遇见yield表达式就返回值并记录位置后中止留待下一次迭代,下一次迭代时执行代码的起始位置是从上一次记录位置开始,直至整个生成器代码运行结束。

4.生成器的应用

1)

def create_num(all_num):
  a, b = 0, 1
  current_num = 0
  while current_num < all_num:
    # print(a)
    yield a
    a, b = b, a+b
    current_num += 1


obj = create_num(10)
while True:
  try:
    ret = next(obj)
    print(ret)
  except Exception as ret:
    break

python 协程中的迭代器,生成器原理及应用实例详解
2)通过send启动生成器
send一般不会放到第一次启动生成器,如果非要这么做,那么传递None
错误示范:

def create_num(all_num):
  a, b = 0, 1
  current_num = 0
  while current_num < all_num:
    ret = yield a
    print(">>>ret>>>", ret)
    a, b = b, a+b
    current_num += 1


obj = create_num(10)

ret = obj.send("hello") #第一个就调用send方法
print(ret)

ret = next(obj)
print(ret)

python 协程中的迭代器,生成器原理及应用实例详解

正确示范:

def create_num(all_num):
  a, b = 0, 1
  current_num = 0
  while current_num < all_num:
    ret = yield a
    print(">>>ret>>>", ret)
    a, b = b, a+b
    current_num += 1


obj = create_num(10)

ret = next(obj)
print(ret)

ret = obj.send("hello")
print(ret)

python 协程中的迭代器,生成器原理及应用实例详解

def create_num(all_num):
  a, b = 0, 1
  current_num = 0
  while current_num < all_num:
    ret = yield a
    print(">>>ret>>>", ret)
    a, b = b, a+b
    current_num += 1


obj = create_num(10)

ret = obj.send(None)
print(ret)

ret = next(obj)
print(ret)

python 协程中的迭代器,生成器原理及应用实例详解
3).使用生成器完成多任务(并发)

import time


def task_1():
  while True:
    print("----1----")
    time.sleep(0.1)
    yield


def task_2():
  while True:
    print("----2----")
    time.sleep(1)
    yield


def main():
  t1 = task_1()
  t2 = task_2()
  while True:
    next(t1)
    next(t2)


if __name__ == '__main__':
  main()

python 协程中的迭代器,生成器原理及应用实例详解

4).gevent使用生成器

导入genvent库
python 协程中的迭代器,生成器原理及应用实例详解

import gevent
import time


def f1(n):
  for i in range(n):
    print(gevent.getcurrent(),i)
    gevent.sleep(0.5)


def f2(n):
  for i in range(n):
    print(gevent.getcurrent(),i)
    gevent.sleep(0.5)


def f3(n):
  for i in range(n):
    print(gevent.getcurrent(),i)
    gevent.sleep(0.5)


print("----1----")
g1 = gevent.spawn(f1,5)
print("----2----")
g2 = gevent.spawn(f2,5)
print("----3----")
g3 = gevent.spawn(f3,5)
g1.join()
g2.join()
g3.join()

python 协程中的迭代器,生成器原理及应用实例详解
修改time.sleep()成gevent.sleep()的简单方法:(打补丁)
只需要导入monkey,写一句代码monkey.patch_all()
,运行时就会自动替换

import gevent
import time
from gevent import monkey

monkey.patch_all()

def f1(n):
  for i in range(n):
    print(gevent.getcurrent(),i)
    time.sleep(0.5)


def f2(n):
  for i in range(n):
    print(gevent.getcurrent(),i)
    time.sleep(0.5)


def f3(n):
  for i in range(n):
    print(gevent.getcurrent(),i)
    time.sleep(0.5)


print("----1----")
g1 = gevent.spawn(f1,5)
print("----2----")
g2 = gevent.spawn(f2,5)
print("----3----")
g3 = gevent.spawn(f3,5)
g1.join()
g2.join()
g3.join()

python 协程中的迭代器,生成器原理及应用实例详解
创建多个gevent时不需一个一个添加join

import gevent
import time
from gevent import monkey

monkey.patch_all()

def f1(n):
  for i in range(n):
    print(gevent.getcurrent(),i)
    time.sleep(0.5)


def f2(n):
  for i in range(n):
    print(gevent.getcurrent(),i)
    time.sleep(0.5)


def f3(n):
  for i in range(n):
    print(gevent.getcurrent(),i)
    time.sleep(0.5)


gevent.joinall([
  gevent.spawn(f1,5),
  gevent.spawn(f2,5),
  gevent.spawn(f3,5)])

python 协程中的迭代器,生成器原理及应用实例详解

更多关于Python相关内容可查看本站专题:《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
在Python中使用第三方模块的教程
Apr 27 Python
Python实现把json格式转换成文本或sql文件
Jul 10 Python
flask中的wtforms使用方法
Jul 21 Python
Python socket模块实现的udp通信功能示例
Apr 10 Python
python中pip的使用和修改下载源的方法
Jul 08 Python
django框架用户权限中的session缓存到redis中的方法
Aug 06 Python
浅谈Python3实现两个矩形的交并比(IoU)
Jan 18 Python
python3+opencv生成不规则黑白mask实例
Feb 19 Python
python实现信号时域统计特征提取代码
Feb 26 Python
python pandas.DataFrame.loc函数使用详解
Mar 26 Python
Python局部变量与全局变量区别原理解析
Jul 14 Python
pyspark对Mysql数据库进行读写的实现
Dec 30 Python
在Python中画图(基于Jupyter notebook的魔法函数)
Oct 28 #Python
python生成器/yield协程/gevent写简单的图片下载器功能示例
Oct 28 #Python
Python SELENIUM上传文件或图片实现过程
Oct 28 #Python
PYTHON实现SIGN签名的过程解析
Oct 28 #Python
Python爬虫使用代理IP的实现
Oct 27 #Python
Python搭建代理IP池实现接口设置与整体调度
Oct 27 #Python
Python搭建代理IP池实现检测IP的方法
Oct 27 #Python
You might like
windows下PHP_intl.dll正确配置方法(apache2.2+php5.3.5)
2014/01/14 PHP
php将12小时制转换成24小时制的方法
2015/03/31 PHP
总结PHP内存释放以及垃圾回收
2018/03/29 PHP
PHP的JSON封装、转变及输出操作示例
2019/09/27 PHP
jQuery初学:find()方法及children方法的区别分析
2011/01/31 Javascript
分享10篇优秀的jQuery幻灯片制作教程及应用案例
2011/04/16 Javascript
JavaScript函数详解
2015/02/27 Javascript
iframe里使用JavaScript控制主页转向的方法
2015/04/03 Javascript
跟我学习javascript的严格模式
2015/11/16 Javascript
Jquery修改image的src属性,图片不加载问题的解决方法
2016/05/17 Javascript
原生JS实现-星级评分系统的简单实例
2016/08/21 Javascript
JSON 必知必会 观后记
2016/10/27 Javascript
深入理解Angularjs中的$resource服务
2016/12/31 Javascript
vue-quill-editor实现图片上传功能
2017/08/08 Javascript
关于Angularjs中跨域设置白名单问题
2018/04/17 Javascript
package.json中homepage属性的作用详解
2020/03/11 Javascript
[49:41]NB vs NAVI Supermajor小组赛A组 BO3 第一场 6.2
2018/06/03 DOTA
python文件比较示例分享
2014/01/10 Python
python中的格式化输出用法总结
2016/07/28 Python
pandas通过索引进行排序的示例
2018/11/16 Python
python Tkinter版学生管理系统
2019/02/20 Python
Python学习笔记之自定义函数用法详解
2019/06/08 Python
Python使用pyautocad+openpyxl处理cad文件示例
2019/07/11 Python
安装python及pycharm的教程图解
2019/10/10 Python
Python基于pip实现离线打包过程详解
2020/05/15 Python
Django 解决model 反向引用中的related_name问题
2020/05/19 Python
CSS3的Flexbox布局的简明入门指南
2016/04/08 HTML / CSS
印度最好的在线药品订购网站:PharmEasy
2018/11/30 全球购物
计算机应用与科学个人的自我评价
2013/11/15 职场文书
大学生就业推荐信范文
2013/11/29 职场文书
离婚协议书包括哪些内容
2014/10/16 职场文书
导游词之台湾安平古堡
2019/12/25 职场文书
深入理解python协程
2021/06/15 Python
Python爬取用户观影数据并分析用户与电影之间的隐藏信息!
2021/06/29 Python
Redis的字符串是如何实现的
2021/10/24 Redis
【海涛教你打dota】体验一超神发条:咱是抢盾专业户
2022/04/01 DOTA