python之路——12
王二学习python的笔记以及记录,如有雷同,那也没事,欢迎交流,wx:wyb199594
复习
1.装饰器
开发原则:开放封闭原则
作用:不改变原函数的调用方式,为函数前后扩展功能
本质:闭包函数
from functools import wraps
def wrapper(f):
@wraps(f)
def inner(*args, **kwargs):
增加功能语句
ret = f(*args, **kwargs)
return ret
return inner
@wrapper
学习内容
装饰器进阶
1.functool.wraps
2.带参数的装饰器
* 接收聚合;传递打散
多个装饰器装饰同一个函数
代码区
1. 装饰器
def outer(*args): print(args) print(*args) def inner(*args): print('inner', args) inner(*args) outer(1, 2, 3, 4) # (* 接收聚合;传递打散)
2.带参数的装饰器
from functools import wraps import time flag = False def timer_out(flag): def wrapper(f): @wraps(f) def inner(*args, **kwargs): if flag: start = time.time() ret = f(*args, **kwargs) end = time.time() print(end - start) return ret else: ret = f(*args, **kwargs) return ret return inner return wrapper @timer_out(flag) def wahaha(): time.sleep(0.01) print('娃哈哈') # wahaha = wrapper(wahaha) wahaha() print(wahaha.__name__)
3.多个装饰器装饰一个函数
def wrapper1(func): # func-----f def inner1(): print('wrapper1_before') func() print('wrapper1_after') return inner1 def wrapper2(func): # inner1 def inner2(): print('wrapper_2_before') func() print('wrapper2_after') return inner2 @wrapper2 # f = wrapper2(f) f----inner2 @wrapper1 # f = wrapper1(f) f----inner1 def f(): print('in f') f()
4.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),# 要求登录成功一次,后续的函数都无需再输入用户名和密码
Flag = True c = 1 def outer(flag): def wrapper(f): def inner(*args, **kwargs): global c li = [] with open('log', 'r', encoding='utf-8') as f1: for line in f1: li.append(line) li[0] = li[0].strip() if flag and c: user_acc = input('请输入账号') user_ans = input('请输入密码') if user_acc == li[0] and user_ans == li[1]: print('认证成功,执行函数') ret = f(*args, **kwargs) c = 0 return ret else: print('认证失败,返回') else: ret = f(*args, **kwargs) return ret return inner return wrapper @outer(Flag) def wahaha(): print('娃哈哈函数体') @outer(Flag) def qqxing(): print('QQ星函数体') wahaha() qqxing() ''' # 老师答案 ''' 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()
5.编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件
''' from functools import wraps def wrapper(f): @wraps(f) def inner(*args,**kwargs): li = [] ret = f(*args,**kwargs) with open('log1','r',encoding='utf-8') as f1, open('log1.bak','w',encoding='utf-8') as f2: for line in f1: li.append(line) li.append(inner.__name__) f2.writelines(li) import os os.remove('log1') os.rename('log1.bak', 'log1') return ret return inner @wrapper def wahaha(): print('娃哈哈函数体') @wrapper def qqxing(): print('QQ星函数体') wahaha() qqxing() ''' # 老师答案 ''' # 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() '''
6.# 进阶作业(选做):
# 1.编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
# 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) 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)

浙公网安备 33010602011771号