1. 程式人生 > >13、生成器函數

13、生成器函數

功能 admin cts name ini httpd 關鍵字 問題 false

一、生成器函數
#生成器函數:只要函數體包含yield關鍵字,該函數的執行結果就是生成器函數
#生成器就是叠代器

# def foo():
# return 1
# return 2
# return 3
# return 4
#
# res1=foo()
# print(res1)
#
# res2=foo()
# print(res2)





# def foo():
# print(‘first‘)
# yield 1
# print(‘second‘)
# yield 2
# print(‘third‘)
# yield 3
# print(‘fourth‘)
# yield 4
# print(‘fifth‘)
#
# g=foo()
# for i in g:
# print(i)



# print(g)
#
# print(next(g)) #觸發叠代器g的執行,進而觸發函數的執行
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))




# def counter(n):
# print(‘start...‘)
# i=0
# while i < n:
# yield i
# i+=1
# print(‘end...‘)
#
#
# g=counter(5)
# print(g)
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))








‘‘‘
yield的功能:
1.相當於為函數封裝好__iter__和__next__
2.return只能返回一次值,函數就終止了,
而yield能返回多次值,每次返回都會將函數暫停,下一次next會從
上一次暫停的位置繼續執行


‘‘‘
二 、表達式形式的yield的用途
#tail -f a.txt | grep ‘python‘


import time
def tail(filepath):
with open(filepath,encoding=‘utf-8‘) as f:
f.seek(0,2)
while True:
line=f.readline().strip()
if line:
yield line
else:
time.sleep(0.2)




# t=tail(‘a.txt‘)
#
# for line in t:
# print(line)

def grep(pattern,lines):
for line in lines:
if pattern in line:
yield line


g=grep(‘python‘,tail(‘a.txt‘))
print(g)

for i in g:
print(i)

#grep -rl ‘python‘ /root


import os

def init(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
next(res)
return res
return wrapper

@init
def search(target):
while True:
search_path=yield
g=os.walk(search_path)
for par_dir,_,files in g:
for file in files:
file_abs_path=r‘%s\%s‘ %(par_dir,file)
# print(file_abs_path)
target.send(file_abs_path)

@init
def opener(target):
while True:
file_abs_path=yield
# print(‘opener func==>‘,file_abs_path)
with open(file_abs_path,encoding=‘utf-8‘) as f:
target.send((file_abs_path,f))

@init
def cat(target):
while True:
file_abs_path,f=yield #(file_abs_path,f)
for line in f:
tag=target.send((file_abs_path,line))
if tag:
break
@init
def grep(target,pattern):
tag=False
while True:
file_abs_path,line=yield tag
tag=False
if pattern in line:
tag=True
target.send(file_abs_path)

@init
def printer():
while True:
file_abs_path=yield
print(file_abs_path)



x=r‘C:\Users\Administrator\PycharmProjects\python17期\day5\a‘



g=search(opener(cat(grep(printer(),‘python‘))))
print(g)

g.send(x)

‘‘‘
面向過程的程序設計:是一種流水線式的編程思路,是機械式
優點:
程序的結構清晰,可以把復雜的問題簡單

缺點:
1 擴展性差


應用場景:
1 linux內核,git,httpd

‘‘‘


三、yield的另外一種用法

#yield的語句形式: yield 1
#yield的表達式形式: x=yield



#協程函數

def deco(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
next(res)
return res
return wrapper

@deco
def eater(name):
print(‘%s ready to eat‘ %name)
food_list=[]
while True:
food=yield food_list
food_list.append(food)
print(‘%s start to eat %s‘ %(name,food))


g=eater(‘alex‘)
# print(g)
# next(g) #等同於 g.send(None)

#

# g.send(‘手指頭‘)
# g.send(‘腳指頭‘)
# g.send(‘別人的手指頭‘)
# g.send(‘別人的腳指頭‘)

# print(g)
print(g.send(‘腳趾頭1‘))
print(g.send(‘腳趾頭2‘))
print(g.send(‘腳趾頭3‘))




#x=yield
#g.send(‘1111‘),先把1111傳給yield,由yield賦值給x
# 然後再往下執行,直到再次碰到yield,然後把yield後的返回值返回









13、生成器函數