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中的生成器和yield详细介绍
Jan 09 Python
python字符串对其居中显示的方法
Jul 11 Python
Python整型运算之布尔型、标准整型、长整型操作示例
Jul 21 Python
python实现单向链表详解
Feb 08 Python
浅谈python中str字符串和unicode对象字符串的拼接问题
Dec 04 Python
python opencv读mp4视频的实例
Dec 07 Python
python实现烟花小程序
Jan 30 Python
Python字符串和正则表达式中的反斜杠('\')问题详解
Sep 03 Python
Django 路由层URLconf的实现
Dec 30 Python
Python操作Jira库常用方法解析
Apr 10 Python
哪种Python框架适合你?简单介绍几种主流Python框架
Aug 04 Python
Python 虚拟环境工作原理解析
Dec 24 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
ThinkPHP调用common/common.php函数提示错误function undefined的解决方法
2014/08/25 PHP
PHP实现简易blog的制作
2016/10/24 PHP
PHP基于PDO实现的SQLite操作类【包含增删改查及事务等操作】
2017/06/21 PHP
PHP fopen函数用法实例讲解
2019/02/15 PHP
利用javascript移动div层-javascript 拖动层
2009/03/22 Javascript
js中的scroll和offset 使用比较的实例与分析
2013/09/29 Javascript
js快速排序的实现代码
2013/12/08 Javascript
js设置function参数默认值(适合没有传参情况)
2014/02/24 Javascript
JQuery为页面Dom元素绑定事件及解除绑定方法
2014/04/23 Javascript
jquery根据属性和index来查找属性值并操作
2014/07/25 Javascript
js闭包实现按秒计数
2015/04/23 Javascript
分享15个大家都熟知的jquery小技巧
2015/12/02 Javascript
jquery对复选框(checkbox)的操作汇总
2016/01/13 Javascript
jquery mobile移动端幻灯片滑动切换效果
2020/04/15 Javascript
Vue结合原生js实现自定义组件自动生成示例
2017/01/21 Javascript
Vue 父子组件、组件间通信
2017/03/08 Javascript
Vue中计算属性computed的示例解读
2017/07/26 Javascript
JavaScript实现图片拖曳效果
2017/09/08 Javascript
JS实现的字符串数组去重功能小结
2019/06/17 Javascript
jQuery实现中奖播报功能(让文本滚动起来) 简单设置数值即可
2020/03/20 jQuery
Echarts在Taro微信小程序开发中的踩坑记录
2020/11/09 Javascript
详解在Python程序中自定义异常的方法
2015/10/16 Python
windows上安装Anaconda和python的教程详解
2017/03/28 Python
Python3实现计算两个数组的交集算法示例
2019/04/03 Python
python接口自动化测试之接口数据依赖的实现方法
2019/04/26 Python
人工神经网络算法知识点总结
2019/06/11 Python
Flask框架学习笔记之表单基础介绍与表单提交方式
2019/08/12 Python
python使用SQLAlchemy操作MySQL
2020/01/02 Python
浅析CSS3中鲜为人知的属性:-webkit-tap-highlight-color
2017/01/12 HTML / CSS
HTML5所有标签汇总及标签意义解释
2015/03/12 HTML / CSS
香港礼品网站:GiftU eshop
2017/09/01 全球购物
幼儿园开学寄语
2014/04/03 职场文书
暑期社会实践个人总结
2015/03/06 职场文书
判断Python中的Nonetype类型
2021/05/25 Python
关于MybatisPlus配置双数据库驱动连接数据库问题
2022/01/22 Java/Android
css弧边选项卡的项目实践
2023/05/07 HTML / CSS