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

 

posted @   滴滴滴  阅读(295)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· 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 让容器管理更轻松!
第一节装饰器复习和知识储备------------第二节闭包函数.函数的作用域关系在定义阶段就有了,和调用阶段无关.11. 节开始yield的另外一种使用方式.主要作用是给闭包函数传送多个值和接收多个值. 第十二节.面向过程编程. 第七节:三元表达式 列表推导式  生成器表达式. 第八节声明式编程. 第九节递归调用.
点击右上角即可分享
微信分享提示