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自定义类的数组排序实现代码
Aug 28 Python
python自定义异常实例详解
Jul 11 Python
python中装饰器级连的使用方法示例
Sep 29 Python
Python编写Windows Service服务程序
Jan 04 Python
python爬虫爬取快手视频多线程下载功能
Feb 28 Python
python 字典 按key值大小 倒序取值的实例
Jul 06 Python
在Python中定义一个常量的方法
Nov 10 Python
python3转换code128条形码的方法
Apr 17 Python
python小程序实现刷票功能详解
Jul 17 Python
python 实现识别图片上的数字
Jul 30 Python
Python with语句和过程抽取思想
Dec 23 Python
python正则表达式匹配IP代码实例
Dec 28 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+SQL 注入攻击的技术实现以及预防办法
2011/01/27 PHP
destoon常用的安全设置概述
2014/06/21 PHP
php使用Jpgraph绘制复杂X-Y坐标图的方法
2015/06/10 PHP
PHP MVC框架skymvc支持多文件上传
2016/05/26 PHP
php微信开发之批量生成带参数的二维码
2016/06/26 PHP
PHP jpgraph库的配置及生成统计图表:折线图、柱状图、饼状图
2017/05/15 PHP
利用PHP获取访客IP、地区位置、浏览器及来源页面等信息
2017/06/27 PHP
PHP explode()函数用法讲解
2019/02/15 PHP
Yii框架ACF(accessController)简单权限控制操作示例
2019/04/26 PHP
Javascript表达式中连续的 &amp;&amp; 和 || 之赋值区别
2010/10/17 Javascript
详解AngularJS中的依赖注入机制
2015/06/17 Javascript
用JavaScript来美化HTML的select标签的下拉列表效果
2015/11/17 Javascript
关于jquery中动态增加select,事件无效的快速解决方法
2016/08/29 Javascript
jQuery实现图片滑动效果
2017/03/08 Javascript
微信小程序 下拉菜单的实现
2017/04/06 Javascript
js封装成插件的步骤方法
2017/09/11 Javascript
深入掌握 react的 setState的工作机制
2017/09/27 Javascript
JavaScript捕捉事件和阻止冒泡事件实例分析
2018/08/03 Javascript
jQuery UI实现动画效果代码分享
2018/08/19 jQuery
2019 年编写现代 JavaScript 代码的5个小技巧(小结)
2019/01/15 Javascript
Vue使用mixin分发组件的可复用功能
2019/09/01 Javascript
基于JavaScript伪随机正态分布代码实例
2019/11/07 Javascript
Vue实现Layui的集成方法步骤
2020/04/10 Javascript
基于JS实现计算24点算法代码实例解析
2020/07/23 Javascript
浅谈用VSCode写python的正确姿势
2017/12/16 Python
Python numpy实现数组合并实例(vstack,hstack)
2018/01/09 Python
Django获取应用下的所有models的例子
2019/08/30 Python
HTML5单页面手势滑屏切换原理分析
2017/07/10 HTML / CSS
NULL是什么,它是怎么定义的
2015/05/09 面试题
IBatis持久层技术
2016/07/18 面试题
喝酒检查书范文
2014/02/23 职场文书
《小猪家的桃花树》教学反思
2014/04/11 职场文书
群众路线四风自我剖析材料
2014/10/08 职场文书
党的群众路线教育实践活动整改落实情况报告
2014/10/28 职场文书
css3中2D转换之有趣的transform形变效果
2022/02/24 HTML / CSS
tomcat默认最大连接数及相关调整方法
2022/05/06 Servers