1. 程式人生 > >day12 裝飾器的進階

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__+'\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