day12 装饰器的进阶

1装饰器

#装饰器的进阶
    #functools.wraps
    #带参数的装饰器
    #多个装饰器装饰同一个函数
#装饰器:
    #本质:闭包函数
    #原则:开放封闭
    #作用:不改变原函数的调用方式的情况下 在函数的前后添加功能

#装饰器
def wrapper(func):
    def inner(*args,**kwargs):
        print('在被装饰的函数执行之前要做的事')
        ret=func(*args,**kwargs)
        print('在被装饰的函数执行之后要做的事')
        return ret
    return inner
@wrapper
def holiday(day):
    print("全体放假%s天" % day)
    return "很开心"

print(holiday(3))
<<<
在被装饰的函数执行之前要做的事
全体放假3天
在被装饰的函数执行之后要做的事
很开心

*的聚合打散

#接收的时候聚合 执行的时候打散
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))
(1, 2, 3, 4)
1 2 3 4
inner: (1, 2, 3, 4)

2.完美装饰器

# 2 完美装饰器
from functools import  wraps
def wrapper(func):
    @wraps(func)
    def inner(*args,**kwargs):
        print('在被装饰的函数执行之前要做的事')
        ret=func(*args,**kwargs)
        print('在被装饰的函数执行之后要做的事')
        return ret
    return inner
@wrapper
def holiday(day):
    '''这是一个放假的通知'''
    print("全体放假%s天" % day)
    return "很开心"


print(holiday(3))
print(holiday.__name__) #打印函数的名字
print(holiday.__doc__)  #打印函数的字符串注释
<<<
在被装饰的函数执行之前要做的事
全体放假3天
在被装饰的函数执行之后要做的事
很开心
holiday
这是一个放假的通知
def wahaha():
    '''
一个打印娃哈哈的函数
    '''
    print('wahha')
print(wahaha.__name__) #查看字符串格式的函数名
print(wahaha.__doc__) #document 查看字符串格式的注释
wahaha()

<<<
wahaha

一个打印娃哈哈的函数
    
wahha

3.作业

#1.编写一个装饰器 为多个函数加上认证功能(用户的账号密码来源于文件)
#要求登陆成功一次 后续的函数都无需再输入用户名和密码
FLAG=False
def login(func):
    def inner(*args,**kwargs):
        global FLAG
        if FLAG:
            ret=func(*args,**kwargs)
            return ret
        else:
            username=input('username:')
            password=input('password:')
            if username=='hhh'and password=='123':
                FLAG=True
                ret = func(*args, **kwargs)
                return ret
            else:
                print('登录失败')
    return inner

@login
def shoplist():
    print('增加一件物品')
@login
def shoplist_remove():
    print('删除一件物品')
shoplist()
shoplist_remove()
<<<
username:hhh
password:123
增加一件物品
删除一件物品
#2 编写装饰器 为多个函数加上记录调用功能  要求每次调用函数都将被调用的函数名称写入文件
def log(func):
    def inner(*args,**kwargs):
        with open('log','a',encoding='utf-8')as f:
            f.write(func.__name__+'
')
        ret=func(*args,**kwargs)
        return ret
    return inner

@log
def shoplist():
    print('增加一件物品')


@log
def shoplist_remove():
    print('删除一件物品')
    return  'shanchu'
shoplist_remove()
shoplist()
# shoplist_remove()
print(shoplist_remove())
<<<
删除一件物品
增加一件物品
删除一件物品
shanchu
 
#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('https://www.baidu.com/')
print(ret)
ret1=get('https://www.baidu.com/')
print(ret1)
ret=get('https://ilovefishc.com/html5/')
print(ret)

<<<
b'<html>
<head>
	<script>
		location.replace(location.href.replace("https://","http://"));
	</script>
</head>
<body>
	<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>'
b'****<html>
<head>
	<script>
		location.replace(location.href.replace("https://","http://"));
	</script>
</head>
<body>
	<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>'
b'****<html>
<head>
	<script>
		location.replace(location.href.replace("https://","http://"));
	</script>
</head>
<body>
	<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>'

4.装饰器的进阶

1.带参数的装饰器

#4 装饰器进阶
#1 带参数的装饰器
#500个函数
import time
FLAGE=False
def timmer_out(flag):
    def timmer_out(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_out
@timmer_out(FLAGE)
def wahaha():
    time.sleep(1)
    print("wahahaha")
@timmer_out(' ')
def er():
    time.sleep(1)
    print("222222")
wahaha()
er()
<<<
wahahaha
222222
1.0006272792816162

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

#2 多个装饰器装饰一个函数
def wrapper1(func):
    def inner(*args,**kwargs):
        print("wrapper1 before func")
        ret=func(*args,**kwargs)
        print("wrapper1 after func")
        return ret
    return inner

def wrapper2(func):
    def inner(*args,**kwargs):
        print("wrapper2 before func")
        ret=func(*args,**kwargs)
        print("wrapper2 after func")
        return ret
    return inner

def wrapper3(func):
    def inner(*args,**kwargs):
        print("wrapper3 before func")
        ret=func(*args,**kwargs)
        print("wrapper3 after func")
        return ret
    return inner

@wrapper1
@wrapper2
@wrapper3
def f():
    print('in f')
    return "hhh"
print(f())
<<<
wrapper1 before func
wrapper2 before func
wrapper3 before func
in f
wrapper3 after func
wrapper2 after func
wrapper1 after func
hhh
原文地址:https://www.cnblogs.com/hi-python/p/10125216.html