迭代器和生成器
1. 复习
(1)情况一
结果:
(2)情况二
结果:
(3)情况三
结果:
装饰器函数:
2.生成器
2.1 生成器函数:
def generator():
print(1)
return 'a'
ret = generator()
print(ret)
只要含有yield关键字的函数都是生成器函数,yield不能和return共用且需要写在函数内
def generator(): print(1) yield 'a' ret = generator() print(ret)
结果:
<generator object generator at 0x0000000005766410>
注意:生成器函数 : 执行之后会得到一个生成器作为返回值
2.2 ret.__next__()
def generator(): print(1) yield 'a' ret = generator() print(ret) print(ret.__next__())
结果:
<generator object generator at 0x000000000564CA98>
1
a
执行过程:
(1)一个迭代
def generator(): print(1) yield 'a' print(2) yield 'b' yield 'c' g = generator() ret=g.__next__() print(ret)
执行结果:
1
a
(2)二次迭代
def generator():
print(1)
yield 'a'
print(2)
yield 'b'
yield 'c'
g = generator()
ret=g.__next__()
print(ret)
ret=g.__next__()
print(ret)
结果:
1 a 2 b
(3)三次迭代
def generator():
print(1)
yield 'a'
print(2)
yield 'b'
yield 'c'
g = generator()
ret=g.__next__()
print(ret)
ret=g.__next__()
print(ret)
ret=g.__next__()
print(ret)
结果:
1
a
2
b
c
(4)可以换成for循环:
def generator(): print(1) yield 'a' print(2) yield 'b' yield 'c' g = generator() for i in g: print(i)
结果同上:
1
a
2
b
c
(5)生成100个娃哈哈,生产一个,处理一个。
def wahaha():
for i in range(100):
yield '娃哈哈%s'%i
g = wahaha()
for i in g:
print(i)
只打印前50个:
def wahaha():
for i in range(100):
yield '娃哈哈%s'%i
g = wahaha()
count = 0
for i in g:
count += 1
print(i)
if count > 50:
break
打印前50个后还可以接着打印下一个:
def wahaha():
for i in range(100):
yield '娃哈哈%s'%i
g = wahaha()
count = 0
for i in g:
count += 1
print(i)
if count > 50:
break
print(g.__next__())
打印前50个后还可以接着打印50个:
def wahaha():
for i in range(100):
yield '娃哈哈%s'%i
g = wahaha()
count = 0
for i in g:
count += 1
print(i)
if count > 50:
break
for i in g:
count += 1
print(i)
if count > 100:
break
与以上区分:
l = [1,2,3,4,5] #可迭代的
#在for形成迭代器
for i in l:
print(i)
if i == 2:
break
for i in l:
print(i)
执行结果(不是接着第一个执行的):
1
2
1
2
3
4
5
类似于:
def wahaha():
for i in range(100):
yield '娃哈哈%s'%i
g = wahaha()
g1 = wahaha()
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g1.__next__())
结果:
娃哈哈0
娃哈哈1
娃哈哈2
娃哈哈0
监听文件输入的例子
一边在文件file,中输入,一边输出查看
def tail(filename): f = open(filename,encoding='utf-8') while True: line = f.readline() if line.strip(): yield line.strip() g = tail('file') for i in g: if 'python' in i: print('***',i)
3.装饰器精讲
4.1普通函数的方法和被装饰函数的方法区别
普通函数:
def wahaha():
'''
一个打印娃哈哈的函数
:return:
'''
print('娃哈哈')
print(wahaha.__name__) #查看字符串格式的函数名
print(wahaha.__doc__) #document
被装饰函数:
def wrapper(func): #func = holiday
def inner(*args,**kwargs): print('在被装饰的函数执行之前做的事') ret = func(*args,**kwargs) print('在被装饰的函数执行之后做的事') return ret return inner @wrapper #holiday = wrapper(holiday) def holiday(day): '''这是一个放假通知''' print('全体放假%s天'%day) return '好开心' print(holiday.__name__) print(holiday.__doc__)
被装饰函数执行结果:
inner
None
想正常打印被装饰函数的方法:
@wraps(func)带参数的装饰器
from functools import wraps
def wrapper(func): #func = holiday
@wraps(func)
def inner(*args,**kwargs):
print('在被装饰的函数执行之前做的事')
ret = func(*args,**kwargs)
print('在被装饰的函数执行之后做的事')
return ret
return inner
@wrapper #holiday = wrapper(holiday)
def holiday(day):
'''这是一个放假通知'''
print('全体放假%s天'%day)
return '好开心'
print(holiday.__name__)
print(holiday.__doc__)
执行结果:
holiday
这是一个放假通知
4.装饰器作业
题目1:
# 1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),
# 要求登录成功一次,后续的函数都无需再输入用户名和密码
执行代码:
FLAG = False def login(func): def inner(*args,**kwargs): global FLAG '''登录程序''' if FLAG: ret = func(*args, **kwargs) # func是被装饰的函数 return ret else: username = input('username : ') password = input('password : ') if username == 'boss_gold' and password == '22222': FLAG = True ret = func(*args,**kwargs) #func是被装饰的函数 return ret else: print('登录失败') return inner @login def shoplist_add(): print('增加一件物品') @login def shoplist_del(): print('删除一件物品') shoplist_add() shoplist_del()
题目2:
# 2.编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件
执行代码:
def log(func): def inner(*args,**kwargs): with open('log','a',encoding='utf-8') as f: f.write(func.__name__+'\n') ret = func(*args,**kwargs) return ret return inner @log def shoplist_add(): print('增加一件物品') @log def shoplist_del(): print('删除一件物品') shoplist_add() shoplist_del() shoplist_del() shoplist_del() shoplist_del() shoplist_del()
进阶作业(选做):
# 1.编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
执行代码:
from urllib.request import urlopen def get(url): code = urlopen(url).read() return code ret = get('http://www.baidu.com') print(ret)
选做2:
为题目1编写装饰器,实现缓存网页内容的功能: # 具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后存到文件中
执行代码:
import os from urllib.request import urlopen def cache(func): def inner(*args,**kwargs): if os.path.getsize('web_cache'): with open('web_cache','rb') as f: return f.read() ret = func(*args,**kwargs) #get() with open('web_cache','wb') as f: f.write(b'*********'+ret) return ret return inner @cache def get(url): code = urlopen(url).read() return code # {'网址':"文件名"} ret = get('http://www.baidu.com') print(ret) ret = get('http://www.baidu.com') print(ret) ret = get('http://www.baidu.com') print(ret)
分成两部分:
5.装饰器进阶内容
5.1带参数的装饰器
500个函数
代码:
import time FLAGE = False def timmer_out(flag): def timmer(func): def inner(*args,**kwargs): if flag: start = time.time() ret = func(*args,**kwargs) end = time.time() print(end-start) return ret else: ret = func(*args, **kwargs) return ret return inner return timmer # timmer = timmer_out(FLAGE) @timmer_out(FLAGE) #wahaha = timmer(wahaha) def wahaha(): time.sleep(0.1) print('wahahahahahaha')
5.2多个装饰器装饰一个函数
推荐书籍:Python核心编程
def wrapper1(func): def inner1(): print('wrapper1 ,before func') ret = func() print('wrapper1 ,after func') return ret return inner1 def wrapper2(func): def inner2(): print('wrapper2 ,before func') ret = func() print('wrapper2 ,after func') return ret return inner2 def wrapper3(func): def inner3(): print('wrapper3 ,before func') ret = func() print('wrapper3 ,after func') return ret return inner3 @wrapper3 @wrapper2 @wrapper1 def f(): print('in f') return '哈哈哈' print(f())
用途:即记录用户的登录情况,又计算这个函数的执行时间
6.作业
1.默写:带参数的装饰器。需要标注代码的执行步骤。
2.整理作业:函数的知识点以及装饰器相关作业。装饰器作业需要自己写一遍,并给作业加注释。
3.周末大作业:实现员工信息表
文件存储格式如下:
id,name,age,phone,job
1,Alex,22,13651054608,IT
2,Egon,23,13304320533,Tearcher
3,nezha,25,1333235322,IT
现在需要对这个员工信息文件进行增删改查。
不允许一次性将文件中的行都读入内存。
基础必做:
a.可以进行查询,支持三种语法:
select 列名1,列名2,… where 列名条件
支持:大于小于等于,还要支持模糊查找。
示例:
select name, age where age>22
select * where job=IT
select * where phone like 133
进阶选做:
b.可创建新员工记录,id要顺序增加
c.可删除指定员工记录,直接输入员工id即可
d.修改员工信息
语法:set 列名=“新的值” where 条件
#先用where查找对应人的信息,再使用set来修改列名对应的值为“新的值”
注意:要想操作员工信息表,必须先登录,登陆认证需要用装饰器完成
其他需求尽量用函数实现
作业要求:
1.今天的第2、3个作业一起打包交上来
2.放在作业2文件夹中
需要交整理的函数相关的思维导图
整理的函数知识点的博客
装饰器作业加注释
3.大作业放在3文件夹中
文件夹中需要包括:
代码
流程图(请上交一张png图片。如果没有合适的画图软件,可以用processon画)
readme文件(请上交一个txt文件,对作业进行一些简单说明,包括作业的整体思路,如何运行,实现了哪些功能,遇到了哪些问题等。)