Python全棧之路Day21
阿新 • • 發佈:2017-11-13
引用 ror iter 一次函數 art 異常 logs generator nes
一. 上節課復習
二. 叠代器
三. 生成器
四. 協程函數
作業
今日總結
初次編輯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(‘餡餅‘))
作業
- 無
今日總結
- 待整理
Python全棧之路Day21