Python全栈之路Day21
Posted 时间就是金钱 我的朋友
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python全栈之路Day21相关的知识,希望对你有一定的参考价值。
初次编辑2017年10月27日,星期五
摘要
引用:Alex
- 迭代器
- 生成器
- 协程函数
一. 上节课复习
- 装饰器
- 无参装饰器
- 有参装饰器
- 装饰器打印原函数信息
import time
from functools import wraps #注意这个
def timmer(func):
@wraps(func) #还有这个
def wrapper():
start_time = time.time()
func()
stop_time = time.time()
print(\'run time is %s \' % (stop_time - start_time))
return wrapper
@timmer #index=timmer(index)
def index():
\'come from index\'
print(\'welcome to oldboy\')
index() #wrapper()
print(index.__doc__) #.__doc__打印函数描述信息,具体不是很了解
二. 迭代器
- 可迭代的
- 只要对象本身有__iter__方法,那它就是可迭代的
- 迭代器
- i = a.iter() #i 即为迭代器
- 可通过__next__ 进行取值
b = {\'a\':1,\'b\':2,\'c\':3}
i = iter(b)
while True:
print(next(i))
#注意:此方法会while会无限循环,报错异常 StopIteration
- 异常捕捉
b = {\'a\':1,\'b\':2,\'c\':3}
i = iter(b)
while True:
try: #注意此行
print(next(i))
except StopIteration: #and this
break # and this
- for 循环机制
for key in d: #d即为d.__iter__() 迭代器放入原位置
print(key) #并且for循环具有异常捕捉的功能
- for 循环实现迭代器
b = {\'a\':1,\'b\':2,\'c\':3}
for i in b:
print(i)
- 为什么要用迭代器
- 优点
- 迭代器提供了一种不依赖于索引的取值方式,这样就可以遍历那些没有索引的可迭代对象了(字典、集合、文件)
- 迭代器与列表相比,迭代器是惰性计算的,更省内存(迭代器在内存中同一时刻只有一个值)
- 缺点
- 无法获取迭代器的长度,使用不如列表索引取值灵活
- 一次性的,只能往后取值,不能倒着取值
- 优点
- 查看可迭代对象与迭代器对象
from collections import Iterable,Iterator
s = \'hello\'
l = [1,2,3]
t = (1,2,3)
d = {\'a\':1}
set1 = (1,2,3,4)
f = open(\'a.txt\')
s.__iter__()
l.__iter__()
t.__iter__()
d.__iter__()
set1.__iter__()
f.__iter__()
#Iterable 为可迭代的
print(isinstance(s,Iterable)) #isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。
print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(d,Iterable))
print(isinstance(set1,Iterable))
print(isinstance(f,Iterable))
- 查看是否是迭代器
print(isinstance(s,Iterator)) #Iterator 为迭代器
print(isinstance(l,Iterator))
print(isinstance(t,Iterator))
print(isinstance(d,Iterator))
print(isinstance(set1,Iterator))
print(isinstance(f,Iterator))
三. 生成器
- 定义:生成器就是一个函数,这个函数内包含有yield这个关键字,可以将函数变成具有序列性,返回多个值
- 生成器与return有何区别
- return只能返回一次函数就彻底结束了,而yield能返回多次值
- yield到底干了什么事
- yield把函数变成生成器(生成器其实就是迭代器)(yield将__next__和__iter__封装到函数内部)
- 用return返回只能返回一次,而yield返回多次
- 函数在暂停以及继续下一次运行时的状态是由yield保存
def test():
print(\'one\')
yield 1
print(\'two\')
yield 2
print(\'three\')
yield 3
g = test() #无输出,此时g为生成器,即把函数变成一个迭代器
print(g) #<generator object test at 0x00000000027E91A8>
res = next(g) #one next触发生成器的执行
print(res) #1
- yield具体应用
def countdown(n):
print(\'start countdown\')
while n >0:
yield n
n -= 1
print(\'done\')
g= countdown(5)
print(next(g)) #start countdown 5
print(next(g)) #4
print(next(g)) #3
print(next(g)) #2
print(next(g)) #1
print(next(g)) #done #会报错
#for循环写法
for i in g:
print(i)
#while循环写法
while True:
try:
print(next(g))
except StopIteration:
break
- 生成器应用
#惰性计算
def func():
n = 0
while True:
yield n
n += 1
f = func()
print(next(f))
- tail命令的最基本实现
import time
def tail(file_path):
with open(file_path,\'r\') as f:
f.seek(0,2) #光标移到最后
while True:
line = f.readline() #读这一行
if not line:
time.sleep(0.5)
continue
else:
print line, #print 输出光标不换行
tail(\'/tmp/a.txt\')
- tail命令通过生成器实现(python2)
import time
def tail(file_path):
with open(file_path,\'r\') as f:
f.seek(0,2) #光标移到最后
while True:
line = f.readline() #读这一行
if not line:
time.sleep(0.5)
print \'=======\'
continue
else:
yield line
g = tail(\'/tmp/a.txt\') #函数变成一个生成器
for line in g:
print line,
- grep命令通过生成器实现(python2)
import time
def tail(file_path):
with open(file_path,\'r\') as f:
f.seek(0,2) #光标移到最后
while True:
line = f.readline() #读这一行
if not line:
time.sleep(0.5)
continue
else:
yield line
g = tail(\'/tmp/a.txt\')
for line in g:
if \'error\' in line:
print line,
- grep命令通过生成器实现且有水流概念
import time
def tail(file_path):
with open(file_path,\'r\') as f:
f.seek(0,2) #光标移到最后
while True:
line = f.readline() #读这一行
if not line:
time.sleep(0.5)
continue
else:
yield line
def grep(pattern,lines): #pattern 为grep所抓取的 lines为输入源
for line in lines:
if pattern in line:
print line,
g = tail(\'/tmp/a.txt\')
grep(\'error\',g)
- tail、grep命令最终版
import time
#定义阶段:定义两个生成器函数
def tail(file_path):
with open(file_path,\'r\') as f:
f.seek(0,2) #光标移到最后
while True:
line = f.readline() #读这一行
if not line:
time.sleep(0.5)
continue
else:
yield line
def grep(pattern,lines): #pattern 为grep所抓取的 lines为输入源
for line in lines:
if pattern in line:
yield line
#调用阶段:得到俩生成器对象
g1 = tail(\'/tmp/a.txt\')
g2 = grep(\'error\',g1)
#使用阶段:next触发执行g2生成器函数
for i in g2:
print i,
四. 协程函数
- 吃包子
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(next(e))
print(e.send(\'包子\'))
print(e.send(\'韭菜包子\')) #send 等同于next 有返回值,但是会把后面的参数传给当前行的yield
print(e.send(\'馅饼\'))
作业
- 无
今日总结
- 待整理
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">
以上是关于Python全栈之路Day21的主要内容,如果未能解决你的问题,请参考以下文章