一、什么是迭代器协议

1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退)

2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法)

3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。

二,为什么要用迭代器

优点:

1:迭代器提供了一种不依赖于索引的取值方式,这样就可以遍历那些没有索引的可迭代对象了(字典,集合,文件)

2:迭代器与列表比较,迭代器是惰性计算的,更节省内存

缺点:

1:无法获取迭代器的长度,使用不如列表索引取值灵活

2:一次性的,只能往后取值,不能倒着取值

 l=['a','b','c','d','e']
i=l.__iter__()
while True:
try:
print(next(i))
except StopIteration:
break

课堂例1

 d={'a':,'b':,'c':}
d.__iter__
for k in d: #d.__iter__()
print(k)

课堂例2

 s={,,,}
for i in s:
print(i) with open('a.txt','r') as f:
for line in f:
print(line) f=open('a.txt','r')
f.__next__
f.__iter__
print(f)
print(f.__iter__()) for line in f: #f.__iter__()
print(line) i=f.__iter__() while True:
try: #异常排查,与StopIteration一起用
print(next(i))
except StopIteration: #异常排查,与try一起用 # except 排除
break

课堂例3

 l=[,,]
print(len(l))
i=l.__iter__() print(next(i))
print(next(i))
print(next(i))
print(next(i)) for x in i:
print(x)
for x in i:
print(x)
for x in i:
print(x)
for x in i:
print(x)

课堂例4

 查看可迭代对象与迭代器对象

 from collections import Iterable,Iterator

 s='hello'
l=[,,]
t=(,,)
d={'a':}
set1={,,,}
f=open('a.txt') 都是可迭代的
s.__iter__()
l.__iter__()
t.__iter__()
d.__iter__()
set1.__iter__()
f.__iter__()
print(isinstance(s,Iterable))
print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(d,Iterable))
print(isinstance(set1,Iterable))
print(isinstance(f,Iterable)) 查看是否是迭代器
print(isinstance(s,Iterator))
print(isinstance(l,Iterator))
print(isinstance(t,Iterator))
print(isinstance(d,Iterator))
print(isinstance(set1,Iterator))
print(isinstance(f,Iterator))

课堂例5

三、生成器

什么是生成器:

可以理解为一种数据类型,这种数据类型自动实现了迭代器协议(其他的数据类型需要调用自己内置的__iter__方法),所以生成器就是可迭代对象.

from collections import Iterator   生成器就是一个函数,这个函数内包含有yield这个关键字  。◕‿◕。

生成器分类及在python中的表现形式:(Python有两种不同的方式提供生成器)

1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行.

2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表.

为何使用生成器:

优点:

Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果。这也是生成器的主要好处。

生成器小结:

1.是可迭代对象

2.实现了延迟计算,省内存

3.生成器本质和其他的数据类型一样,都是实现了迭代器协议,只不过生成器附加了一个延迟计算省内存的好处,其余的可迭代对象可没有这点好处,记住喽!!!

生成器与return的区别:return只能返回一次函数就彻底结束了,而yield能返回多次值
                 
yield功能:

1.yield把函数变成生成器-->生成器本质就是迭代器,相当于把__iter__和__next__方法封装到函数内部

2.用return返回值能返回一次,而yield返回多次

3.函数暂停以及继续运行的状态是通过yield保存的

插一嘴:

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

 >>> L = [x * x for x in range()]
>>> L
[, , , , , , , , , ]
>>> g = (x * x for x in range())
>>> g
<generator object <genexpr> at 0x1022ef630>

创建Lg的区别仅在于最外层的[]()L是一个list,而g是一个generator。

我们可以直接打印出list的每一个元素,但我们怎么打印出generator的每一个元素呢?

如果要一个一个打印出来,可以通过next()函数获得generator的下一个返回值:

 >>> next(g)

 >>> next(g)

 >>> next(g)

 >>> next(g)

 >>> next(g)

 >>> next(g)

 >>> next(g)

 >>> next(g)

 >>> next(g)

 >>> next(g)

 >>> next(g)
Traceback (most recent call last):
File "<stdin>", line , in <module>
StopIteration

我们讲过,generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

生成器本质就是迭代器

 def func():
n=
while True:
yield n
n+= g=func() res=next(g)
res=next(g) for i in g:
pass

yield的表达式形式:

 food=yield

 def eater(name):
print('%s start to eat' %name)
while True:
food=yield
print('%s eat %s' %(name,food)) e=eater('zhejiangF4')

e.send与next(e)的区别
          1.如果函数内yield是表达式形式,那么必须先next(e)
          2.二者的共同之处是都可以让函数在上次暂停的位置继续运行,不一样的地方在于send在触发下一次代码的执行时,会顺便给yield传一个值

 def test():
print('one')
yield #return
print('two')
yield #return
print('three')
yield #return
print('four')
yield #return
print('five')
yield #return g=test()
print(g)
# print(isinstance(g,Iterator))
g.__iter__()
g.__next__() res=next(g)
print(res) res=next(g)
print(res) res=next(g)
print(res) res=next(g)
print(res) for i in g:
print(i)

课堂例1

 def func():
n=
while True:
yield n
n+= f=func()
print(next(f))

课堂例2

 import time
def tail(file_path):
with open(file_path,'r') as f:
f.seek(,)
while True:
line=f.readline()
if not line:
time.sleep(0.3)
continue
else:
# print(line)
yield line
tail('/tmp/a.txt')

课堂例3

 def countdown(n):
print('start coutdown')
while n > 0:
yield n #
n-=1
print('done') g=countdown(5)
print(g) print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g)) for i in g: #iter(g)
print(i) while True:
try:
print(next(g))
except StopIteration:
break

课堂例4

四、协程函数

定义:如果在一个函数内部yield的使用方式是表达式形式的话,如x=yield,那么该函数成为协程函数  。◕‿◕。

 #例子

 1 def eater(name):
print('%s start to eat food' %name)
food_list=[]
while True:
food=yield food_list
print('%s get %s ,to start eat' %(name,food))
food_list.append(food)
print('done')
e=eater('钢蛋')
print(e)
12 print(next(e))
print(e.send('包子'))
print(e.send('韭菜馅包子'))
15 print(e.send('大蒜包子'))

为协程函数添加装饰器:

 def timmer(func):
def wrapper(*args,**kwargs):
e=func(*args,**kwargs)
next(e)
return e
return wrapper @timmer #eater=timmer(eater)
def eater(name):
print('%s start to eat food' %name)
food_list=[]
while True:
food=yield food_list
print('%s get %s ,to start eat' %(name,food))
food_list.append(food)
e = eater('egon') #wrapper('egon')
# print(e)
# next(e)
print(e.send('包子'))
print(e.send('包子')) #以下每send一次都会执行一次结果
print(e.send('包子'))
print(e.send('包子'))

补充:

 def init(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
next(res)
return res
return wrapper @init #eater=init(eater)
def eater(name):
print('%s start to eat' % name)
food_list=[]
while True:
food = yield food_list
print('%s eat %s' % (name, food))
food_list.append(food) e = eater('zhejiangF4') #wrapper('zhengjiangF4')
# print(e)
# next(e) #e.send(None) print(e.send(''))
print(e.send(''))
print(e.send(''))
print(e.send(''))
print(e.send(''))

五、协程函数的应用

面向过程的编程思想:流水线式的编程思想,在设计程序时,需要把整个流程设计出来

优点:   1:体系结构更加清晰

2:简化程序的复杂度

缺点:可扩展性极其的差,所以说面向过程的应用场景是:不需要经常变化的软件,如:linux内核,httpd,git等软件

旁白: 此实例包含了装饰器、迭代器、生成器、协程函数、os模块中walk命令,需要好好记住! ♥♥♥♥♥。◕‿◕。♥♥♥♥♥

 #grep -rl 'python' C:\egon
import os,time
def init(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
next(res)
return res
return wrapper #找到一个绝对路径,往下一个阶段发一个
@init
def search(target):
'找到文件的绝对路径'
while True:
dir_name=yield #dir_name='C:\\egon'
print('车间search开始生产产品:文件的绝对路径')
time.sleep(2)
g = os.walk(dir_name)
for i in g:
# print(i)
for j in i[-1]:
file_path = '%s\\%s' % (i[0], j)
target.send(file_path) @init
def opener(target):
'打开文件,获取文件句柄'
while True:
file_path=yield
print('车间opener开始生产产品:文件句柄')
time.sleep(2)
with open(file_path) as f:
target.send((file_path,f)) @init
def cat(target):
'读取文件内容'
while True:
file_path,f=yield
print('车间cat开始生产产品:文件的一行内容')
time.sleep(2)
for line in f:
target.send((file_path,line)) @init
def grep(pattern,target):
'过滤一行内容中有无python'
while True:
file_path,line=yield
print('车间grep开始生产产品:包含python这一行内容的文件路径')
time.sleep(0.2)
if pattern in line:
target.send(file_path) @init
def printer():
'打印文件路径'
while True:
file_path=yield
print('车间printer开始生产产品:得到最终的产品')
time.sleep(2)
print(file_path) g=search(opener(cat(grep('python',printer()))))
g.send('C:\\egon')
g.send('D:\\dir1')
g.send('E:\\dir2')

面向过程实例

python基础----迭代器、生成器、协程函数及应用(面向过程实例)的更多相关文章

  1. python装饰器,迭代器,生成器,协程

    python装饰器[1] 首先先明白以下两点 #嵌套函数 def out1(): def inner1(): print(1234) inner1()#当没有加入inner时out()不会打印输出12 ...

  2. Python基础-迭代器&生成器&装饰器

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 我现在有个需求,看 ...

  3. python(18)- 协程函数及应用

    协程 def init(func): def wrapper(*args,**kwargs): obj = func(*args,**kwargs) next(obj) return obj retu ...

  4. Python基础篇-day11 - 协程

    本节主要内容: 1.Gevent协程2.Select\Poll\Epoll异步IO与事件驱动3.RabbitMQ队列 1.Gevent协程 1.1协程的好处 无需线程上下文切换的开销无需原子操作锁定及 ...

  5. Python连载42-异步协程函数

    一.  asyncio 1.python3.4开始引入标准库之中,内置对异步io的支持 2.asyncio本身是一个消息循环 3.步骤: (1)创建消息循环 (2)把协程导入 (3)关闭 4.举例: ...

  6. Python基础线程和协程

    线程: 优点:共享内存,IO操作时,创造并发操作 缺点:枪战资源 线程不是越多越好,具体案例具体分析,请求上下文切换耗时 IO密集型适用于线程,IO操作打开文件网络通讯类,不需要占用CPU,只是由CP ...

  7. python基础之协程函数、列表表达式、生成器表达式

    一.协程函数 协程函数的定义?如果在一个函数内部yield的使用方式是表达式形式的话,如x=yield,那么该函数称为协程函数 协程函数补充: def init(func): def wrapper( ...

  8. Py修行路 python基础 (十二) 协程函数应用 列表生成式 生成器表达式

    一.知识点整理: 1.可迭代的:对象下有_iter_方法的都是可迭代的对象 迭代器:对象._iter_()得到的结果就是迭代器 迭代器的特性: 迭代器._next_() 取下一个值 优点: 1.提供了 ...

  9. python协程函数应用 列表生成式 生成器表达式

    协程函数应用 列表生成式 生成器表达式   一.知识点整理: 1.可迭代的:对象下有_iter_方法的都是可迭代的对象 迭代器:对象._iter_()得到的结果就是迭代器 迭代器的特性: 迭代器._n ...

随机推荐

  1. 【SpringCloud】第十二篇: 断路器监控(Hystrix Turbine)

    前言: 必需学会SpringBoot基础知识 简介: spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选. ...

  2. leetcode27_C++Remove Element

    给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成 ...

  3. 【RL系列】马尔可夫决策过程——Gambler's Problem

    Gambler's Problem,即“赌徒问题”,是一个经典的动态编程里值迭代应用的问题. 在一个掷硬币游戏中,赌徒先下注,如果硬币为正面,赌徒赢回双倍,若是反面,则输掉赌注.赌徒给自己定了一个目标 ...

  4. NodeJS实现同步的方法

    NodeJS被打上了单线程.非阻塞.事件驱动…..等标签. 在单线程的情况下,是无法开启子线程的.经过了很久的研究,发现并没有thread函数!!!但是有时候,我们确实需要“多线程”处理事务.node ...

  5. 与面试官谈笑风生 | Python面向对象之访问控制

    Python从设计之初就是一门面向对象的语言,面向对象思想的第一个要素就是封装.所谓封装,通俗的讲就是类中的属性和方法,分为公有和私有,公有可以被外界访问,私有不能被外界访问,这就是封装中最关键的概念 ...

  6. java面向对象的栈 队列 优先级队列的比较

    栈 队列 有序队列数据结构的生命周期比那些数据库类型的结构(比如链表,树)要短得多.在程序操作执行期间他们才被创建,通常用他们去执行某项特殊的任务:当完成任务之后,他们就会被销毁.这三个数据结构还有一 ...

  7. 复利计算器app发布

    复利计算器app发布 抱歉:由于无法实现服务端的持续开启,发布的app仅为简单的单机版,暂时舍弃了c/s版本的一些功能,如:投资动态管理功能. 应用详情博客:请点击这里 apk下载地址1(百度手机助手 ...

  8. vim 编码方式的设置

    和所有的流行文本编辑器一样,Vim 可以很好的编辑各种字符编码的文件,这当然包括UCS-2.UTF-8 等流行的 Unicode 编码方式.然而不幸的是,和很多来自 Linux 世界的软件一样,这需要 ...

  9. 01_Java基础_第1天(Java概述、环境变量、注释、关键字、标识符、常量)_讲义

    今日内容介绍 1.Java开发环境搭建 2.HelloWorld案例 3.注释.关键字.标识符 4.数据(数据类型.常量) 01java语言概述 * A: java语言概述 * a: Java是sun ...

  10. C++进阶之_类型转换

    C++进阶之_类型转换 1.类型转换名称和语法 C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是: TYPE b = (TYPE)a C++风格的类型转换提供了4种类型转换操 ...