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 BeautifulSoup中文乱码问题的2种解决方法
Apr 22 Python
Python判断文件和文件夹是否存在的方法
May 21 Python
一键搞定python连接mysql驱动有关问题(windows版本)
Apr 23 Python
解决Linux系统中python matplotlib画图的中文显示问题
Jun 15 Python
python僵尸进程产生的原因
Jul 21 Python
Python 实现选择排序的算法步骤
Apr 22 Python
python3 requests库文件上传与下载实现详解
Aug 22 Python
解决Django layui {{}}冲突的问题
Aug 29 Python
python__name__原理及用法详解
Nov 02 Python
python如果快速判断数字奇数偶数
Nov 13 Python
NumPy统计函数的实现方法
Jan 21 Python
python 对象真假值的实例(哪些视为False)
Dec 11 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
中国站长站 For Dede4.0 采集规则
2007/05/27 PHP
PHP自动选择 连接本地还是远程数据库
2010/12/02 PHP
将酷狗krc歌词解析并转换为lrc歌词php源码
2014/06/20 PHP
[原创]php实现子字符串位置相互对调互换的方法
2016/06/02 PHP
javascript事件问题
2009/09/05 Javascript
ext combox 下拉框不出现自动提示,自动选中的解决方法
2010/02/24 Javascript
js switch case default 的用法示例介绍
2013/10/23 Javascript
用jquery等比例控制图片宽高的具体实现
2014/01/28 Javascript
js语法学习之判断一个对象是否为数组
2014/05/13 Javascript
jquery拖拽排序简单实现方法(效果增强版)
2016/02/16 Javascript
Bootstrap列表组学习使用
2017/02/09 Javascript
Angularjs中的ui-bootstrap的使用教程
2017/02/19 Javascript
javascript算法之二叉搜索树的示例代码
2017/09/12 Javascript
浅析vue中的MVVM实现原理
2019/03/04 Javascript
JavaScript canvas实现跟随鼠标事件
2020/02/10 Javascript
利用webpack理解CommonJS和ES Modules的差异区别
2020/06/16 Javascript
[02:25]DOTA2英雄基础教程 虚空假面
2014/01/02 DOTA
python字符串替换的2种方法
2014/11/30 Python
使用Python对MySQL数据操作
2017/04/06 Python
浅谈python socket函数中,send与sendall的区别与使用方法
2017/05/09 Python
python中的变量如何开辟内存
2018/06/26 Python
Python3的高阶函数map,reduce,filter的示例详解
2019/07/23 Python
详解Python绘图Turtle库
2019/10/12 Python
wxPython实现分隔窗口
2019/11/19 Python
Python笔记之观察者模式
2019/11/20 Python
GAP阿联酋官网:GAP UAE
2017/11/30 全球购物
精灵市场:Pixie Market
2019/06/18 全球购物
Waterford英国官方网站:世界上最受欢迎的优质水晶品牌
2019/08/17 全球购物
Stührling手表官方网站:男女高品质时尚手表的领先零售商
2021/01/07 全球购物
Linux的主要特性
2014/10/06 面试题
班组长的岗位职责
2013/12/09 职场文书
医学生个人求职信范文
2014/02/07 职场文书
铁路工务反思材料
2014/02/07 职场文书
建筑工程专业大学生求职信
2014/04/23 职场文书
四风问题党员个人整改措施
2014/10/27 职场文书
2015年远程教育工作总结
2015/05/20 职场文书