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 相关文章推荐
Python3实现生成随机密码的方法
Aug 23 Python
Django中几种重定向方法
Apr 28 Python
Python编程实现控制cmd命令行显示颜色的方法示例
Aug 14 Python
基于python代码实现简易滤除数字的方法
Jul 17 Python
python保存二维数组到txt文件中的方法
Nov 15 Python
Python内存管理实例分析
Jul 10 Python
Django实现发送邮件功能
Jul 18 Python
django如何实现视图重定向
Jul 24 Python
python pandas 时间日期的处理实现
Jul 30 Python
python 实现简单的FTP程序
Dec 27 Python
OpenCV 使用imread()函数读取图片的六种正确姿势
Jul 09 Python
Python tkinter制作单机五子棋游戏
Sep 14 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
linux php mysql数据库备份实现代码
2009/03/10 PHP
php中使用redis队列操作实例代码
2013/02/07 PHP
spl_autoload_register与autoload的区别详解
2013/06/03 PHP
Alliance vs Liquid BO3 第二场2.13
2021/03/10 DOTA
JavaScript是否可实现多线程  深入理解JavaScript定时机制
2009/12/22 Javascript
JavaScript中各种编码解码函数的区别和注意事项
2010/08/19 Javascript
JS中confirm,alert,prompt函数区别分析
2011/01/17 Javascript
Jquery时间验证和转换工具小例子
2013/07/01 Javascript
js中数组排序sort方法的原理分析
2014/11/20 Javascript
jQuery中用dom操作替代正则表达式
2014/12/29 Javascript
jQuery中bind()方法用法实例
2015/01/19 Javascript
jQuery实现多级下拉菜单jDropMenu的方法
2015/08/28 Javascript
在javascript中随机数 math random如何生成指定范围数值的随机数
2015/10/21 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记9)
2015/12/24 Javascript
实例讲解Jquery中隐藏hide、显示show、切换toggle的用法
2016/05/13 Javascript
浅析jQuery 遍历函数,javascript中的each遍历
2016/05/25 Javascript
微信小程序 动态绑定事件并实现事件修改样式
2017/04/13 Javascript
关于javascript sort()排序你可能忽略的一点理解
2017/07/18 Javascript
解决在vue项目中,发版之后,背景图片报错,路径不对的问题
2018/03/06 Javascript
vue.js中实现登录控制的方法示例
2018/04/23 Javascript
Vue微信项目按需授权登录策略实践思路详解
2018/05/07 Javascript
JavaScript中为事件指定处理程序的五种方式分析
2018/07/27 Javascript
vue-cli配置flexible过程详解
2019/07/04 Javascript
vue中echarts图表大小适应窗口大小且不需要刷新案例
2020/07/19 Javascript
[03:56]DOTA2完美大师赛趣味视频之小鸽子和Mineski打台球
2017/11/24 DOTA
python mysqldb连接数据库
2009/03/16 Python
零基础写python爬虫之使用urllib2组件抓取网页内容
2014/11/04 Python
python动态参数用法实例分析
2015/05/25 Python
python中的global关键字的使用方法
2019/08/20 Python
pytorch .detach() .detach_() 和 .data用于切断反向传播的实现
2019/12/27 Python
利用CSS3动画实现圆圈由小变大向外扩散的效果实例
2018/09/10 HTML / CSS
自我鉴定书面格式
2014/01/13 职场文书
安全第一课观后感
2015/06/18 职场文书
教师教育心得体会
2016/01/19 职场文书
七个Python必备的GUI库
2021/04/27 Python
win10清理dns缓存
2022/04/19 数码科技