Day 22 生成器yield表达式及内置函数(一丢丢)
本日知识点:
################################### #一、上节课复习:在for循环式,调用对象内部的__iter__方法, # 把他们变成了可迭代对象然后for循环调用可迭代对象的__next__方法去取值, # 而且for循环会捕捉StopIteration异常,以终止迭代 ################################### # def func(n): # while n > 0: # yield n # print("*"*6) # n -= 1 # # g=func(5) # #第一个 # print(next(g)) # print(next(g)) # print(next(g)) # print(next(g)) # print(next(g)) # #第二个 等价于前面第一个 # for i in g: #next(g) # print(i) ################################### #二、send的效果: # 1:先从为暂停位置的那个yield传一个值,然后yield会把值赋值x # 2:与next的功能一样 #注意:要先启动,执行到yield的位置处 ################################### # def init(func): # ''' # 装饰器:预启动生成器,到位置yield处,以便send传值 # :param func: # :return: # ''' # def wrapper(*args,**kwargs): # g=func(*args,**kwargs) # next(g) # return g # return wrapper # # @init #foo=init(foo) # def foo(): # ''' # 函数:测试send对yield的传值效果 # :return: # ''' # print('starting') # while True: # print("*"*8) # x=yield #return 1 # print("8"*8) # print('value : ',x) # # 测试部分:********************************** # g = foo() # print(next(g)) #赋值后,迭代器开始迭代 # print(next(g)) # print(next(foo())) #!!!!!!!每次相当于从头开始 # print(next(foo())) # g.send(2) #要先启动,所以编写装饰器,预启动 # print(g) # # print('='*30) # print(g.send(1)) # print('='*30) # print(g.send(2)) # print('='*30) # print(next(g)) # print('='*30) # print(g.send(None)) #g.send(None)等同于next(g) ################################### # 二、应用:生成器表达式:含yield的函数! yield 不仅可以返回值还可以接收值。注意,开始需要预启动(send) ################################### # def init(func): # def wrapper(*args,**kwargs): # g = func(*args,**kwargs) # next(g) # return g # return wrapper # # @init # 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)) # # e = eater("alex") # # print(next(e)) #通过装饰器,解决这个语句! # print(e.send("狗屎")) # print(e.send("猫屎")) # print(e.send("alex屎粑粑")) #其二 ************************************举例:自动供应食材,并输出吃饭过程 # def init(func): # ''' # 装饰器:预启动函数 # :param func: # :return: # ''' # def wrapper(*args,**kwargs): # # print("修饰") # g = func(*args,**kwargs) # next(g) # return g # return wrapper # # @init # def eat_food(name): # ''' # 生成器:迭代执行 # :param name: # :return: # ''' # print("开始吃饭了=======》 ") # food_list = [] # while True: # x = yield food_list # food_list.append(x) # print("%s 现在吃 %s" %(name,x)) # print(food_list) # # # gg = eat_food("dachao") # # gg.send("鸡腿") # # def make_food(people,n): # ''' # 自动生成食材 # :param people: # :param n: # :return: # ''' # print("*"*10) # for i in range(n): # people.send("SHIT %s" %(i)) # # gg = eat_food("alex") # make_food(gg,10) ################################### # yield 功能嵌套,多函数协作 面向过程编程思想! # 应用:模拟功能===》 grep -rl 'root' /etc 便览文件目录,并把含关键字的文件地址返回打印 ################################### import os def init(func): ''' 装饰器:预启动 :param func: :return: ''' def wrapper(*args,**kwargs):x g = func(*args,**kwargs) next(g) return g return wrapper #阶段一:递归地找文件的绝对路径,把路径发给阶段二 def search_1(target,start_path): g = os.walk(start_path) for par_dir,_,files in g: for file in files: file_path = r"%s\%s" %(par_dir,file) target.send(file_path) #阶段二:收到文件路径,打开文件获取获取对象,把文件对象发给阶段三 @init def opener(target): while True: file_path = yield with open(file_path,encoding="utf-8") as f: target.send((file_path,f)) #阶段三:收到文件对象,for循环读取文件的每一行内容,把每一行内容发给阶段四 @init def cat(target): while True: file_path,f = yield for line in f : res = target.send((file_path,line)) if res: break #阶段四:收到一行内容,判断root是否在这一行中,如果在,则把文件名发给阶段五 @init def grep(target,pattern): tag = False while True: file_path,line = yield tag tag = False if pattern in line: target.send(file_path) tag = True #阶段五:收到文件名,打印结果 @init def printer(): while True: file_path = yield print(file_path) start_path =r"D:\Python\study\Day_10\a_10" search_1(opener(cat(grep(printer(),"dachao"))),start_path)
作业:
################################### # yield 功能嵌套,多函数协作 面向过程编程思想! # 应用:模拟功能===》 grep -rl 'root' /etc 便览文件目录,并把含关键字的文件地址返回打印 ################################### import os def init(func): def wrapper(*args,**kwargs): g = func(*args,**kwargs) next(g) return g return wrapper #阶段一:递归地找文件的绝对路径,把路径发给阶段二 def search_path(target,file_path): g = os.walk(file_path) #获取绝对路径 for path_1,_,path_3 in g: for file in path_3: res = r"%s\%s" %(path_1,file) target.send(res) #阶段二:收到文件路径,打开文件获取获取对象,把文件对象发给阶段三 @init def open_path(target): while True: file_path = yield with open(file_path,encoding="utf-8") as f: target.send((file_path,f)) #阶段三:收到文件对象,for循环读取文件的每一行内容,把每一行内容发给阶段四 @init def read_file(target): while True: file_path,f = yield for i in f: res = target.send((file_path,i)) if res: break #阶段四:收到一行内容,判断root是否在这一行中,如果在,则把文件名发给阶段五 @init def grep_file(target,content): tag = False while True: file_path,i = yield tag #True停止迭代 tag = False if content in i: target.send(file_path) tag = True #阶段五:收到文件名,打印结果 @init def printer(): while True: file_path = yield print(file_path) file_path = r"D:\Python\study\Day_10\a_10" search_path(open_path(read_file(grep_file(printer(),"dachao"))),file_path) ######################################### # 选做作业 # l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]] # 一个列表嵌套很多层,用递归取出所有的值 ######################################### # l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]] # # # def get_list(list): # for i in list: # if isinstance(i,int): #isinstance 函数 # print(i,end=",") # else: # get_list(i) # # get_list(l)