1. 程式人生 > 其它 >函式裝飾器

函式裝飾器

函式裝飾器

1.裝飾器簡易版本

給函式新增統計時間的功能

import time
def index()
		time.sleep(3)
		print('原函式')
def outer(func):  # func指向的是函式名index
    # func = index
    def get_time():
        start_time = time.time()
        func()
        end_time = time.time()
        print('函式執行時間:%s' % (end_time - start_time))
    return get_time  # 將get_time函式名返回出去
index = outer(index)  # outer(index函式名)
# 左側的變數名index指代是函式名get_time
index()
      	

2.解決引數問題

import time
def index():
    time.sleep(3)
    print('函式1')
def login(num):
    time.sleep(1)
    print('函式%s'%num)
def outer(func):  # func指向的是函式名login
    # func = login
    def get_time(*args,**kwargs):
        start_time = time.time()
        func(*args,**kwargs)
        end_time = time.time()
        print('函式執行時間:%s' % (end_time - start_time))
    return get_time  # 將get_time函式名返回出去
login = outer(login)
login('2')
index = outer(index)
index()

3.解決返回值問題

# 接收原函式的返回值
import time
def index():
    time.sleep(3)
    print('函式1')
    return 'from index'
def login(num):
    time.sleep(1)
    print('函式%s'% num)
    return 'from login'
def outer(func):  # func指向的是函式名login
    # func = login
    def get_time(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)  # 接收被裝飾函式的返回值
        end_time = time.time()
        print('函式執行時間:%s' % (end_time - start_time))
        return res  # 執行完get_time之後返回被裝飾函式執行之後的返回值
    return get_time  # 將get_time函式名返回出去
index = outer(index)
res = index()
print(res)
login = outer(login)
res1 = login('1')
print(res1)

4.認證裝飾器

import time
def index():
    time.sleep(1)
    print('百萬大獎等你來拿 趕快加入我們吧!!!')
def home():
    time.sleep(1)
    print('學學學 一天到晚就是學 卷死你們這些傢伙')
def register():
    time.sleep(1)
    print('註冊功能')
# 給index函式新增認證功能

"""
在呼叫index之前需要使用者輸入使用者名稱和密碼
    正確才可以呼叫
    錯誤直接拒絕
"""
# 定義一個用於記錄使用者是否登入的資料
is_login = {'is_login':False}


def login_auth(func):
    def auth(*args,**kwargs):
        # 1.1 先判斷使用者是否已經登入
        if is_login.get('is_login'):
            # 3.正常執行函式index
            res = func(*args, **kwargs)
            return res
        # 1.先獲取使用者的使用者名稱和密碼
        username = input('username>>>:').strip()
        password = input('password>>>:').strip()
        # 2.校驗使用者名稱和密碼是否正確
        if username == 'tony' and password == '123':
            # 3.正常執行函式index
            res = func(*args,**kwargs)
            # 4.將記錄使用者登入狀態的資料修改
            is_login['is_login'] = True
            return res
        else:
            print('使用者名稱或密碼錯誤 無法執行函式')
    return auth
index = login_auth(index)
index()
home = login_auth(home)
home()
register = login_auth(register)
register()

5.裝飾器固定模版

def outer(func):
  	def inner(*args,**kwargs):
      	print('執行函式之前可以新增的額外功能')
        res = func(*args,**kwargs)  # 執行被裝飾的函式
        print('執行函式之後可以新增的額外功能')
        return res  # 將被裝飾函式執行之後的返回值返回
    return inner
  

6.裝飾器語法糖

​ 裝飾器語法糖是寫規範
​ 語法糖必須緊貼在被裝飾物件的上方
​ 裝飾器語法糖內部原理
​ 會自動將下面緊貼著的被裝飾物件名字當做引數傳給裝飾器函式呼叫

def outer(func):
    def inner(*args, **kwargs):
        print('執行函式之前可以新增的額外功能')
        res = func(*args, **kwargs)  # 執行被裝飾的函式
        print('執行函式之後可以新增的額外功能')
        return res  # 將被裝飾函式執行之後的返回值返回
    return inner
@outer  # index = outer(index)
def index(*args, **kwargs):
    print('from index')
@outer  # home = outer(home)
def home():
    print('from home')

7.雙層語法糖

import time
def get_time(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)  # 執行被裝飾的函式
        end_time = time.time()
        print('函式執行時間:%s'%(end_time-start_time))
        return res  # 將被裝飾函式執行之後的返回值返回
    return inner
# 校驗使用者登入裝飾
def login_auth(func):
    def inner(*args, **kwargs):
        # 1.先獲取使用者的使用者名稱和密碼
        username = input('username>>>:').strip()
        password = input('password>>>:').strip()
        # 2.校驗使用者名稱和密碼是否正確
        if username == 'tony' and password == '123':
            res = func(*args, **kwargs)  # 執行被裝飾的函式
            return res  # 將被裝飾函式執行之後的返回值返回
        print('使用者名稱或密碼錯誤 無許可權執行')
    return inner
@login_auth  # 上面沒有語法糖之後就用被修飾的函式名接受
@get_time  # 先從下面的開始執行
def index():
    time.sleep(1)
    print('from index')
index()

8.裝飾器修復技術

from functools import wraps
def outer(func):
    @wraps(func)  # 修復技術就是為了讓被裝飾物件更加不容易被察覺裝飾了
    def inner(*args, **kwargs):
        print('執行函式之前可以新增的額外功能')
        res = func(*args, **kwargs)  # 執行被裝飾的函式
        print('執行函式之後可以新增的額外功能')
        return res  # 將被裝飾函式執行之後的返回值返回
    return inner


@outer  # index = outer(index)
def index():
    print('from index')
print(index)
help(index)

def home():
    """這是一個home函式"""
    print('from home')
# help(index)
# help(home)
# print(index)
# help(len)