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日期操作学习笔记
Oct 07 Python
详解Python中的__init__和__new__
Mar 12 Python
python创建一个最简单http webserver服务器的方法
May 08 Python
python如何读写csv数据
Mar 21 Python
numpy.transpose对三维数组的转置方法
Apr 17 Python
PyCharm代码整体缩进,反向缩进的方法
Jun 25 Python
python处理DICOM并计算三维模型体积
Feb 26 Python
Django中信号signals的简单使用方法
Jul 04 Python
tesserocr与pytesseract模块的使用方法解析
Aug 30 Python
Python内建序列通用操作6种实现方法
Mar 26 Python
Python脚本破解压缩文件口令实例教程(zipfile)
Jun 14 Python
matplotlib部件之矩形选区(RectangleSelector)的实现
Feb 01 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
简单的php数据库操作类代码(增,删,改,查)
2013/04/08 PHP
PHP+MySQL存储数据常见中文乱码问题小结
2016/06/13 PHP
php array_reverse 以相反的顺序返回数组实例代码
2017/04/11 PHP
laravel实现登录时监听事件,添加登录用户的记录方法
2019/09/30 PHP
在IE6下发生Internet Explorer cannot open the Internet site错误
2010/06/21 Javascript
javaScript 删除字符串空格多种方法小结
2012/10/24 Javascript
不同的jQuery API来处理不同的浏览器事件
2012/12/09 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(五)可移动地图的实现
2013/01/23 Javascript
简单实例处理url特殊符号&amp;处理(2种方法)
2013/04/02 Javascript
jquery复选框checkbox实现删除前判断
2014/04/20 Javascript
深入浅析JavaScript的API设计原则
2016/06/14 Javascript
原生js仿jquery animate动画效果
2016/07/13 Javascript
仿iframe效果Aajx文件上传实例
2016/11/18 Javascript
vue+vuex+axios实现登录、注册页权限拦截
2018/03/09 Javascript
vue项目在安卓低版本机显示空白的原因分析(两种)
2018/09/04 Javascript
基于vue v-for 多层循环嵌套获取行数的方法
2018/09/26 Javascript
arctext.js实现文字平滑弯曲弧形效果的插件
2019/05/13 Javascript
Javascript 对象(object)合并操作实例分析
2019/07/30 Javascript
JQuery实现折叠式菜单的详细代码
2020/06/03 jQuery
在阿里云服务器上配置CentOS+Nginx+Python+Flask环境
2016/06/18 Python
利用python将pdf输出为txt的实例讲解
2018/04/23 Python
Python实现的基于优先等级分配糖果问题算法示例
2018/04/25 Python
Tensorflow: 从checkpoint文件中读取tensor方式
2020/02/10 Python
django 实现手动存储文件到model的FileField
2020/03/30 Python
Pytorch高阶OP操作where,gather原理
2020/04/30 Python
python中threading开启关闭线程操作
2020/05/02 Python
Python pandas对excel的操作实现示例
2020/07/21 Python
Python识别处理照片中的条形码
2020/11/16 Python
选购世界上最好的美妆品:Cult Beauty
2017/11/03 全球购物
美国美食礼品篮网站:Gourmet Gift Baskets
2019/12/15 全球购物
工程质量月活动方案
2014/02/19 职场文书
车辆转让协议书
2014/04/15 职场文书
2014年人事工作总结范文
2014/11/19 职场文书
2016年中学端午节主题活动总结
2016/04/01 职场文书
初中教务主任竞聘演讲稿(范文)
2019/08/20 职场文书
OpenCV图像变换之傅里叶变换的一些应用
2021/07/26 Python