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天
在被裝飾的函數執行以後要作的事
很開心

*的聚合打散html

#接收的時候聚合 執行的時候打散
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__+'\n')
        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>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.replace("https://","http://"));\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>\r\n</body>\r\n</html>'
b'****<html>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.replace("https://","http://"));\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>\r\n</body>\r\n</html>'
b'****<html>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.replace("https://","http://"));\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>\r\n</body>\r\n</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
相關文章
相關標籤/搜索