昨日内容复习
装饰器:
原则:开放封闭原则
作用:在不改变原函数的调用方式的情况下,在函数的前后添加功能
装饰器的本质:闭包函数
def wrapper(f):
def inner(*args, **kwargs):
print('在被装饰函数之前做的事')
ret = f(*args, **kwargs)
print('在被装饰函数之后做的事')
return ret
return inner
@wrapper
def holiday(day):
print('全体放假%s天'%day)
return 'ok'
res = holiday(3)
print(res)
作业讲解
第一题:编写装饰器,为多个函数加上认证的功能(用户的账号和密码来源于文件)要求登录成功一次,后续函数都无需再输入用户名和密码
FLAG = False # 刚开始没有登录,是False状态
def login(func):
def inner(*args, **kwargs):
global FLAG
''' 登入程序 '''
if FLAG:
ret = func(*args, **kwargs)
return ret
else:
usernanme = input('username:')
password = input('password:')
if usernanme == 'mashengde' and password == '123456':
FLAG = True
ret = func(*args, **kwargs)
else:
print('账号密码错误!')
return ret
return inner
@login
def shoplist_add():
print('增加一个物品')
@login
def shoplist_del():
print('删除一个物品')
shoplist_add()
shoplist_del()
第二题:编写装饰器,为多个函数加上记录调用功能,要求梅调用函数都将被调用的函数名称写入文件
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_del()
shoplist_del()
进阶作业:
第一题:编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
from urllib.request import urlopen
def get(url):
html_code = urlopen(url).read()
return html_code
ret = get('http://www.baidu.com')
print(ret)
第二题:为题目1编写装饰器,实现缓存网页内容的功能,具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就先从文件中读取网页内容,否则就去下载
import os
from urllib.request import urlopen
def cache(func):
def inner(*args, **kwargs):
if os.path.getsize('log'):
with open('log', 'rb') as f:
return f.read()
ret = func(*args, **kwargs)
with open('log', 'wb')as f:
f.write(b'*************'+ret)
return ret
return inner
@cache
def get(url):
html_code = urlopen(url).read()
return html_code
ret = get('http://www.baidu.com')
print(ret)
ret = get('http://www.baidu.com')
print(ret)
今日内容
生成器
本质:迭代器
生成器函数:
函数中有yiled关键字函数就是生成器函数,且不能和return共用,需要卸载函数内部
例子 ;
def generator():
print(1)
yield 'a' # 只要有yield就是生成器函数
ret = generator()
print(ret)
生成器函数执行后会形成生成器作为返回值
def generator():
print(1)
yield 'a' # 只要有yield就是生成器函数
ret = generator()
print(ret)
print(ret.__next__())
yiled不会结束,但每一次往下执行需要一次—next—
def generator():
print(1)
yield 'a'
print(2)
yield 'b'
ret = generator()
print(ret)
print(ret.__next__())
print(ret.__next__())
for循环执行
def generator():
print(1)
yield 'a'
print(2)
yield 'b'
ret = generator()
for i in ret:
print(i)
监听器小例子
def tail(filename):
f = open(filename, encoding='utf-8')
while True:
line = f.readline()
if line:
yield line.strip()
g = tail('你好')
for i in g:
print(i)
装饰器进阶
带参数的装饰器(三层装饰器)
import time
FLAG = True
def out(flag):
def timer(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 timer
@out(FLAG)
def wahah():
time.sleep(0.1)
print('hellp')
@out(FLAG)
def erguotou():
time.sleep(0.1)
print('hahahah')
wahah()
erguotou()
**多个装饰器装饰一个函数**
def wrapper1(func):
def inner1():
print('1,before')
func()
print('1,after')
return inner1
def wrapper2(func):
def inner2():
print('2,before')
func()
print('2,after')
return inner2
@wrapper1
@wrapper2
def f():
print('in f')
f()