python笔记(装饰器进阶)

装饰器进阶
@*arg:接收就是元组,调用就是打散
1.wraps内部装饰器的使用

from functools import wraps
def wahaha():
    '''
    一个函数
    '''
    print('哇哈哈')
print(wahaha.__name__)        #获取函数内的打印中的字符串
print(wahaha.__doc__)         #获取函数内的注释字符串

2.装饰器内部wraps的使用(可在带装饰器的函数中获取打印的字符串和注释的字符串)

from functools import wraps
 
functools.wraps
from functools import wraps
def timer(f):
    @wraps(f)
    def inner(*args,**kwargs):
        '''在被装饰函数之前要做的事'''
        ret = f(*args,**kwargs)
        '''在被装饰函数之后要做的事'''
        return ret
    return inner#5
    
@timer
def func(a,b):#2
    time.sleep(0.01)#9
    print('大家好!',a,b)#10
    return '新年好'
print(func.__name__)

3.带参数的装饰器(如果FLAG为真就执行装饰内容,反之不执行)

import time

FLAGE = False                         #用于判断需不需要执行装饰的内容

def timmer_out(flag):#1
    def timmer(func):
        def inner(*arg,**karg):#5
            if flag:
                start = time.time()
                ret = func(*arg,**karg)
                end = time.time()
                print(end - start)
                return ret
            else:
                ret = func(*arg, **karg)
                return ret
        return inner
    return timmer

@timmer_out(FLAGE)            #timmer = timer_out(FLAGE)(#2) @timmer == (wahaha = timmer(wahaha))(#3)
def wahaha():
    time.sleep(0.1)
    print('wahahahah')
@timmer_out(FLAGE)
def erguotou():
    time.sleep(0.01)
    print('nihaoya')

wahaha()#4
erguotou()

在这里插入图片描述

4.多个装饰器装饰同一个函数

def wrapper1(f): #1
def inner1(): #8
print(‘wrapper1,befor’) #9
ret = f()
print(‘wrapper1,after’) #11
return ret
return inner1 #f–>func

def wrapper2(f):             #f-->inner1                                  #2
    def inner2():                                                         #6
        print('wrapper2,befor')                                           #7
        ret = f()
        print('wrapper2,after')                                           #12
        return ret
    return inner2

@wrapper2       #func = wrapper2(func)-->wrapper2(inner1)==inner2         #4
@wrapper1       #func = wrapper1(func) --> inner1                         #3
def func():                   #找最近的装饰符
    print('你好鸭!')                                                     #10
    return '好的'                                                         #13
print(func())  #==>inerr2()                                               #5

输出结果:

wrapper2,befor
wrapper1,befor
你好鸭!
wrapper1,after
wrapper2,after
好的

y9ibG9nLmNzZG4ubmV0L3FxXzQxNDMzMTgz,size_27,color_FFFFFF,t_70)
作业:
1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码

flag = False
def login(func):
    def inner(*arg,**karg):
        global flag
        '''登陆程序'''
        if flag:
            ret = func(*arg,**karg)
            return ret
        else:
            username = input('username:')
            password = input('password:')
            if username == 'boss_gold' and password == '222':
                flag = True
                ret = func(*arg,**karg)
            else:
                print('登陆失败!')
    return inner
@login
def wrapper():
    print('增加一件物品')
@login
def shoplist_add():
    print('删除一件物品')
wrapper()
shoplist_add()

2.编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件

def log(func):
    def inner(*arg,**karg):
        with open('log','a',encoding='utf-8') as f:
           f.write(func.__name__+'\n')
        reg = func(*arg,**karg)
        return reg
    return inner

@log
def wrapper():
    print('增加一件物品')
@log
def shoplist_add():
    print('删除一件物品')
wrapper()

进阶作业(选做):
1.编写下载网页内容的函数, 要求功能是:用户传入一个u1,函数返回下载页面的结果
2.为题目1编写装饰器,实现缓存网页内容的功能
具体:实现下载的页面存放于文件 中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后

from urllib.request import urlopen
import os
def cache(func):
    def inner(*arg,**karg):
        if os.path.getsize('web_cath'):             #查看文件是否为空
            with open('web_cath','rb') as f:
                return f.read()

        ret = func(*arg,**karg)   #请求网页
        with open('web_cath','wb') as f:
            f.write(b'***'+ret)                         #将请求的结果写到文件里
        return ret
    return inner

@cache
def get(url):
    html = urlopen(url).read()
    return html

ret = get('http://www.baidu.com')
print(ret)
ret = get('http://www.baidu.com')
print(ret)
ret = get('http://www.baidu.com')
print(ret)

猜你喜欢

转载自blog.csdn.net/qq_41433183/article/details/83445172