python第四周迭代器生成器序列化面向过程递归
1 | |
第一节装饰器复习和知识储备------------
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 第一节装饰器复习和知识储备 - - - - - - - - - - - - def wrapper( * args, * * kwargs): index( * args, * * kwargs) # * 的作用是把位置参数打散传值到args=[a,b,c] # **的作用是把关键字参数打散传值到kwargs=[a,b,c] def index(a,b,c): print (a,b,c) wrapper( 'tt' , 'pppp' ,c = 'vvv' ) 二:函数可以被当做数据传递. 函数可以当做参数传给另外一个函数 一个函数的返回值也可以是一个函数 三.名称空间和作用域. 名称空间分为三种: 内置名称空间:python解释器启动则生效 全局名称空间:执行python文件时生效 局部名称空间:调用函数时,临时生效,函数调用结束时失效 加载顺序 = = > 内置 - - - >全局 - - - >局部名称空间 名字查找的顺序是: 局部 - - >全局 - - - >内置名称空间 作用: 分两种: 全局作用域 全局存活 和局部作用域. 临时存活 函数内部使用 局部有效 |
第二节闭包函数.函数的作用域关系在定义阶段就有了,和调用阶段无关.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | 第二节闭包函数.函数的作用域关系在定义阶段就有了,和调用阶段无关. 定义在函数内部的函数叫闭包函数. 包含对外部作用域而不是全局作用域的引用. x = 1 def outter(): x = 2 def inner(): print (x) return inner f = outter() f() #获取的f不止inner函数,还有外面的一层作用域. from urllib.request import urlopen def outget(url): def get(): return urlopen(url).read() return get baidu = outget( 'http://www.baidu.com' ) print (baidu()) 第三迭代器. = = = = = = = = = = = 不依赖于索引取值的方式 一般迭代可以有索引的 l = [ 1 , 2 , 3 , 4 ] i = 0 while i < len (l): print (l[i]) i + = 1 print ( 'hello' .__iter__()) print ( 'hello' .__iter__) 可迭代的对象.只要对象内只有__iter__方法,obj.__iter__ 可迭代对象有:字符串 列表 元祖 字典 文件 迭代器对象对象既内只有__iter__方法,又内置有__next__方法. 文件是迭代器对象 可迭代对象不一定是迭代器对象,迭代器对象一定是可迭代对象 dic = { 'aa' : 1 , 'bb0' : 2 , 'cc' : 3 } dc = dic.__iter__() dc.__next__ #可迭代对象执行了__iter__()方法后就变成了迭代器对象. #######获取迭代器的下一个值 dic = { 'aa' : 1 , 'bb0' : 2 , 'cc' : 3 } dc = dic.__iter__() print (dc.__next__()) - - - - - - - - - - - - - - - - - - - - - - 不依赖于索引的取值. with open ( 'tt2.txt' , 'r' ,encoding = 'utf-8' ) as f: print ( next (f)) print ( next (f)) print ( next (f)) dic = { 'aa' : 1 , 'bb0' : 2 , 'cc' : 3 } tt = dic.__iter__() print ( next (tt)) print ( next (tt)) print ( next (tt)) dic = { 'aa' : 1 , 'bb0' : 2 , 'cc' : 3 } dc = dic.__iter__() while True : try : print ( next (dc)) except : break = = = = = = = = = = = = = 第八迭代器下. for 就是系统的迭代器. for 循环会把可迭代对象,变为迭代器. 迭代器对象没有值,只有在 next 的时候才获取值. 这样更节省内存. aa = range ( 1000000000 ) tt = aa.__iter__() print (tt.__next__()) print (tt.__next__()) print (tt.__next__()) 很多字典列表变为迭代器对象了. from collections import Iterable,Iterator print ( isinstance ( 'hello' ,Iterable)) print ( isinstance ( 'hello' ,Iterator)) - - - - - - - - - - - - - - - - 第九生成器.只要定义函数内部出现 yield 关键字, #name再调用该函数,将不会立即执行该函数代码,将会得到该结果就是生成器对象. 生成器的本质就是迭代器. return 只能返回一次值. yield 可以返回多次值. def fc(): print ( "111111111" ) yield 1 print ( "2222" ) yield 2 print ( "33333333" ) yield 3 g = fc() print (g) print ( next (g)) print ( next (g)) ############## <generator object fc at 0x02C944E0 > 111111111 1 2222 2 yield 的功能: 为我们提供了一种自定义迭代器的方式 对比 return ,可以返回多次值,挂起函数的运行状态. 一次 yield 对应一次 next 多了报错. def fc(): print ( "111111111" ) yield 1 , 2 , 'yyy' print ( "2222" ) yield 2 print ( "33333333" ) yield 3 g = fc() for i in g: print (i) for i in g: print (i) #第二次for循环不会取值. 一次就将for循环的值取完了. = = = = = = = = = = = = = = = = = 10 节生成器下 def my_range(start,stop,step): while start < stop: yield start start + = step f = my_range( 1 , 4 , 1 ) print ( next (f)) print ( next (f)) print ( next (f)) print ( next (f)) print ( next (f)) def my_range(start,stop,step): while start < stop: yield start #这里获取到的是一个生成器,通过next()可以获取到生成器的值. start + = step f = my_range( 1 , 4 , 1 ) # print(next(f)) # print(next(f)) # print(next(f)) for i in f: print (i) - - - - - - - - - - - 模仿grep 和tail的功能的实现 #tail 'tt2.txt'|grep '404' #把每次tail的值传给greo_file函数 import time def tailpath(f_ph): with open (f_ph, 'r' ,encoding = 'utf-8' ) as f: f.seek( 0 , 2 ) while True : line = f.readline() if line: yield line else : time.sleep( 1 ) def grep_file(): lines = tailpath( 'tt2.txt' ) for line in lines: if '404' in line: print (line, '****' ) # break grep_file() - - - - - - - - - - - - - - - - 第二版 #tail 'tt2.txt'|grep '404' #把每次tail的值传给greo_file函数 import time def tailpath(f_ph): with open (f_ph, 'r' ,encoding = 'utf-8' ) as f: f.seek( 0 , 2 ) while True : line = f.readline() if line: yield line else : time.sleep( 1 ) def grep_file(patten,lines): for line in lines: if patten in line: print (line, '****' ) break grep_file( '404' ,tailpath( 'tt2.txt' )) - - - 测试的写文件 with open ( 'tt2.txt' , 'a' ,encoding = 'utf-8' ) as a: a.write( "aaaaaaaaaa\n" ) a.write( "404fggggggggggggggg\n" ) # print('404' in '404fggggggggggggggg') - - - - - - - - - - - - - - - - 进化版 #tail 'tt2.txt'|grep '404' #把每次tail的值传给greo_file函数 import time def tailpath(f_ph): with open (f_ph, 'r' ,encoding = 'utf-8' ) as f: f.seek( 0 , 2 ) while True : line = f.readline() if line: yield line else : time.sleep( 1 ) def grep_file(patten,lines): for line in lines: if patten in line: yield line gp = grep_file( '404' ,tailpath( 'tt2.txt' )) # for g in gp: # print(g) print ( next (gp)) |
11. 节开始yield的另外一种使用方式.主要作用是给闭包函数传送多个值和接收多个值.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | = = = = = = = = = = = 11 节开始 - - - - - - yield 的另外一种使用方式.主要作用是给闭包函数传送多个值和接收多个值. - - - - - - - - - - - - - - - - - - - - - send的作用一个是给 yield 赋值,一个是往下走. def eat(name): print ( '开始了 %s' % name) while True : food = yield print ( '%s 吃了 %s' % (name,food)) g = eat( 'egon' ) g.send( None ) g.send( '骨头' ) - - - - - - - - - - - - - - - - - - - - - - send给的是 yield 变量获取的的值,tt = g.send('')返回值是 yield 后面的值. def eat(name): print ( '开始了 %s' % name) while True : food = yield 123 print ( '%s 吃了 %s' % (name,food)) g = eat( 'egon' ) g.send( None ) g.send( '骨头' ) print (g.send( '骨头' )) g.send( '骨头' ) next (g) - - - - send的值给了赋值得的变量,send获取了 yield 的返回值. 开始了 egon egon 吃了 骨头 egon 吃了 骨头 123 egon 吃了 骨头 egon 吃了 None def eat(name): list_food = [] print ( '开始了 %s' % name) while True : food = yield list_food print ( '%s 吃了 %s' % (name,food)) list_food.append(food) g = eat( 'egon' ) g.send( None ) #或者next(g) g.send( '骨头' ) print (g.send( 'shi' )) #----- #开始了 egon #egon 吃了 骨头 #egon 吃了 shi #['骨头', 'shi'] - - - - - - - - - - 一个函数多次传值. def tt(): while True : x = yield print (x) g = tt() g.send( None ) g.send( 11 ) g.send( 2 ) g.close() - - - - - - - - - - - - - - - - - - - - - send的作用一个是给 yield 赋值,一个是往下走. def eat(name): print ( '开始了 %s' % name) while True : food = yield print ( '%s 吃了 %s' % (name,food)) g = eat( 'egon' ) g.send( None ) g.send( '骨头' ) - - - - - - - - - - - - - - - - - - - - - - send给的是 yield 变量获取的的值,tt = g.send(' ')返回值是yield后面的值. def eat(name): print(' 开始了 % s ' %name) while True: food=yield 123 print(' % s 吃了 % s ' %(name,food)) g=eat(' egon ') g.send(None) g.send(' 骨头 ') print(g.send(' 骨头 ')) g.send(' 骨头 ') next(g) ----send的值给了赋值得的变量,send获取了yield的返回值. 开始了 egon egon 吃了 骨头 egon 吃了 骨头 123 egon 吃了 骨头 egon 吃了 None def eat(name): list_food=[] print(' 开始了 % s ' %name) while True: food=yield list_food print(' % s 吃了 % s ' %(name,food)) list_food.append(food) g=eat(' egon ') g.send(None) #或者next(g) g.send(' 骨头 ') print(g.send(' shi ')) #----- #开始了 egon #egon 吃了 骨头 #egon 吃了 shi #[' 骨头 ', ' shi'] - - - - - - - - - - 一个函数多次传值. def tt(): while True : x = yield print (x) g = tt() g.send( None ) g.send( 11 ) g.send( 2 ) g.close() |
第十二节.面向过程编程.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | = = = = = = = 第十二节.面向过程编程. import os tt = os.walk(r 'D:\PycharmProjects\wadsd' ) print (tt) print ( next (tt)) #os.walk返回一个生成器 #next(tt) 返回三个值得元祖,第一个值当前目录,第二个值当前目录下的目录 第三个值 返回当前目录下的文件. <generator object walk at 0x02A144E0 > ( 'D:\\PycharmProjects\\wadsd' , [ '.git' , '.idea' , 'day1' , 'day2' , 'day3' , 'day4' ], [ '11.txt' , '文件.py' ]) - - - - - - - - - - - 打印目录下的文件的绝对路径 import os def search(target): g = os.walk(r 'D:\PycharmProjects\wadsd' ) for dirname,_,files in g: for file in files: abs_path = r '%s\%s' % (dirname, file ) target.send(abs_path) def opener(): while True : abs_path = yield print (abs_path) g = opener() next (g) search(g) - - - - - - - 再写一遍 import os def get_path(pp): g = os.walk(r 'D:\PycharmProjects\wadsd\day4' ) for base_apth,_,files in g: abs_path = '%s\%s' % (base_apth,files) pp.send(abs_path) def pp(): while True : abs_path = yield print (abs_path) tt = pp() next (tt) get_path(tt) - - - - - - - - - - - - - - - - - - - - - - - - - - - - 这个要多抄一些. import os def gv_fun(fun): def wrapper( * args, * * kwargs): gg = fun( * args, * * kwargs) next (gg) return gg return wrapper @gv_fun def pp(): while True : abs_path = yield print (abs_path) def get_path(pp): g = os.walk(r 'D:\PycharmProjects\wadsd\day4' ) for base_apth,_,files in g: abs_path = '%s\%s' % (base_apth,files) pp.send(abs_path) get_path(pp()) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - import os def wrapper(fun): def inner( * args, * * kwargs): gg = fun( * args, * * kwargs) next (gg) return gg #最后要返回 生成器 return inner def get_path(pt): #这个是最后执行的方法 #这里获取了生成器为了下一步的send发送信息 g_p = os.walk(r 'D:\PycharmProjects\wadsd\day4' ) for base_dir,_,files in g_p: abs_path = '%s\%s' % (base_dir,files) pt.send(abs_path) #装饰器是装饰生成器,应为生成器每次生成器每次生成之后都需要做一次next操作, # 装饰器是装饰一个对象每次方法前或者方法后执行的内容 @wrapper def pt(): while True : abs_p = yield print (abs_p) get_path(pt()) |
第七节:三元表达式 列表推导式 生成器表达式.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | 第七节:三元表达式 列表推导式 生成器表达式. 1. 三元表达式 # def my_max(x,y): # if x>y: # print(x) # return(x) # else: # # return y # # print(my_max(10,20)) x = 10 y = 5 tt = x if x > y else y print (tt) a = 111 b = 222 pp = a if a>b else b print (pp) name = input ( "ttt:" ) res = 'SB' if name = = 'alex' else 'NB' print (res) 2. 列表推导式 生成一个列表 l = [] for i in range ( 1 , 11 ): # print(i) res = 'egg%s' % ( str (i)) l.append(res) print (l) tt = [ 'egg%s' % ( str (i)) for i in range ( 1 , 10 )] print (tt) [ '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ] pp = [ str (i) for i in 'hello' ] print (pp) - - - 列表推导式衍生版本,后面加条件 tt = [ str (i) for i in range ( 10 ) if i> 6 and i< 10 ] print (tt) 3. 生成器表达式,将列表表达式的[]中括号改为()小括号 tt = [ 'egg%s' % ( str (i)) for i in range ( 5 , 1000 ) if i> 500 and i< 600 ] print (tt) tt2 = ( 'egg%s' % ( str (i)) for i in range ( 5 , 1000 ) if i> 500 and i< 600 ) print (tt2) print ( next (tt2)) #列表表达式生成的是一个生成器. <generator object <genexpr> at 0x031554E0 > egg501 #生成器表达式的优点是一次生成一个值在内存. |
第八节声明式编程.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | 第八节声明式编程. # 将names=['egon','alex_sb','wupeiqi','yuanhao']中的名字全部变大写) names = [ 'egon' , 'alex_sb' , 'wupeiqi' , 'yuanhao' ] NM = [i.upper() for i in names] print (NM) # 将names=['egon','alex_sb','wupeiqi','yuanhao']中以sb结尾的名字过滤掉,然后保存剩下的名字长度 names = [ 'egon' , 'alex_sb' , 'wupeiqi' , 'yuanhao' ] nn = [i for i in names if not i.endswith( 'sb' )] print (nn) # 求文件a.txt中最长的行的长度(长度按字符个数算,需要使用max函数) l = [] with open (r 'tt2.txt' , 'r' ,encoding = 'utf-8' ) as f: tt = [ len (line) for line in f] # (len(line) for line in f) 写一个生成器比列表更好 print (tt) print ( max (tt) # 4、求文件a.txt中总共包含的字符个数?思考为何在第一次之后的n次sum求和得到的结果为0?(需要使用sum函数) with open ( 'tt2.txt' , encoding = 'utf-8' ) as f: print ( sum ( len (line) for line in f)) # tesla,1000000,10 # chicken,200,1 # # 求总共花了多少钱? # # 打印出所有商品的信息,格式为[{'name':'xxx','price':333,'count':3},...] # # 求单价大于10000的商品信息,格式同上 with open ( 'tt2.txt' , 'r' ,encoding = 'utf-8' ) as f: info_name = [ 'name:%s' % (line.split( ',' )[ 0 ]) for line in f] print (info_name) with open ( 'tt2.txt' , 'r' ,encoding = 'utf-8' ) as f: info_sum = [ 'sum:%s' % ( int (line.split( ',' )[ 1 ]) * int (line.split( ',' )[ 2 ])) for line in f] print (info_sum) tt = (i for i in range ( 10 )) print ( max (tt)) # print(max(tt)) 上面第二行报错的原因是获取的g是一个生成器, max 相当于迭代器,第一次迭代后无法做二次迭代相当于 for 循环. with open ( 'tt2.txt' , 'r' ,encoding = 'utf-8' ) as f: print ( max (( len (i) for i in f))) |
第九节递归调用.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #递归调用在调用一个函数的时候直接或者间接,调用了自己 def fun1(n): print ( "===" ,n) fun1(n + 1 ) fun1( 1 ) #python最大调用层数10000 = = = 997 = = = 998Traceback (most recent call last): import sys print (sys.getrecursionlimit()) # 1000 |
时来天地皆同力,运去英雄不自由
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!