day3(装饰器的进阶)

1.复习

 装饰器的进阶
     functools.wraps
     带参数的装饰器
     多个装饰器装饰同一个函数
 装饰器
 开发原则 : 开放封闭原则
 装饰器的作用 :在不改变原函数的调用方式的情况下,在函数的前后添加功能
 装饰器的本质 : 闭包函数
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 '好开心'
 ret = holiday(3)
 print(ret)

 def outer(*args):
     print(args)
     print(*args)
     def inner(*args):
         print('inner : ',args)
     inner(*args)
 outer(1,2,3,4)   #==outer(*[1,2,3,4])  #==outer(*(1,2,3,4))

print(holiday.__name__)
print(holiday.__doc__)
ret = holiday(3)   #inner
print(ret)

2.作业

 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.编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件
 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()

 进阶作业(选做):
 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)  #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)
带参数的装饰器
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')

 @timmer_out(FLAGE)
 def erguotou():
     time.sleep(0.1)
     print('erguotoutoutou')

 wahaha()
 erguotou()

多个装饰器装饰一个函数
def wrapper1(func):
    def inner1():
        print('wrapper1 ,before func')
        ret = func()
        print('wrapper1 ,after func')
        return ret
    return inner1

def wrapper2(func):
    
def wrapper3(func):
    
@wrapper3
@wrapper2
@wrapper1
def f():
    print('in f')
    return '哈哈哈'

print(f())

记录用户的登录情况
计算这个函数的执行时间

猜你喜欢

转载自blog.csdn.net/qq_36227329/article/details/81154860