python裝飾器

閉包:

關於閉包,即函數定義和函數表達式位於另一個函數的函數體內(嵌套函數)。而且,這些內部函數可以訪問它們所在的外部函數中聲明的所有局部變量、參數。當其中一個這樣的內部函數在包含它們的外部函數之外被調用時,就會形成閉包。也就是說,內部函數會在外部函數返回後被執行。而當這個內部函數執行時,它仍然必需訪問其外部函數的局部變量、參數以及其他內部函數。這些局部變量、參數和函數聲明(最初時)的值是外部函數返回時的值,但也會受到內部函數的影響。

def outer():
    name = 'alex'

    def inner():
        print("在inner裏打印外層函數的變量",name)

    return inner


f = outer() 

f()

閉包的意義:

返回的函數對象,不僅僅是一個函數對象,在該函數外還包裹了一層作用域,這使得,該函數無論在何處調用,優先使用自己外層包裹的作用域

裝飾器:

一個裝飾器(decorator)只是一個帶有一個函數作爲參數並返回一個函數的閉包

裝飾器的作用就是爲已經存在的函數或對象添加額外的功能

例一:

不加參數的裝飾器:

# _*_coding:utf-8_*_
user_status = False #用戶登錄了就把這個改成True


def login(func): #把要執行的模塊從這裏傳進來

    def inner():#再定義一層函數
        _username = "alex" #假裝這是DB裏存的用戶信息
        _password = "abc!23" #假裝這是DB裏存的用戶信息
        global user_status

        if user_status == False:
            username = input("user:")
            password = input("pasword:")

            if username == _username and password == _password:
                print("welcome login....")
                user_status = True
            else:
                print("wrong username or password!")

        if user_status == True:
            func() # 看這裏看這裏,只要驗證通過了,就調用相應功能

    return inner # 用戶調用login時,只會返回inner的內存地址,下次再調用時加上()纔會執行inner函數


@login   #america = login(america)
def america():
    #login() #執行前加上驗證
    print("----歐美專區----")


def japan():
    print("----日韓專區----")


@login
def henan():
    #login() #執行前加上驗證
    print("----河南專區----")

henan()
例二:


帶參數的裝飾器:

# _*_coding:utf-8_*_

user_status = True #用戶登錄了就把這個改成True


def login(auth_type): #把要執行的模塊從這裏傳進來
    def auth(func):
        def inner(*args, **kwargs):#再定義一層函數
            if auth_type == "qq":
                _username = "alex" #假裝這是DB裏存的用戶信息
                _password = "abc!23" #假裝這是DB裏存的用戶信息
                global user_status
                if user_status == False:
                    username = input("user:")
                    password = input("pasword:")

                    if username == _username and password == _password:
                        print("welcome login....")
                        user_status = True
                    else:
                        print("wrong username or password!")

                if user_status == True:
                    return func(*args,**kwargs) # 看這裏看這裏,只要驗證通過了,就調用相應功能
            else:
                print("only support qq ")
        return inner #用戶調用login時,只會返回inner的內存地址,下次再調用時加上()纔會執行inner函數

    return auth


def home():
    print("---首頁----")


@login('qq')
def america(style):
    #login() #執行前加上驗證
    print("----歐美專區----")


def japan(style):
    print("----日韓專區----")


@login('qq')   ##  henan = login('qq')(henan('3p'))
def henan(style):
    '''
    :param style: 喜歡看什麼類型的,就傳進來
    :return:
    '''
    #login() #執行前加上驗證
    print("----河南專區----")


home()

# #那用戶調用時依然寫
america('3p')

henan('3p')

例三:

計算函數運行時間的裝飾器:

# _*_coding:utf-8_*_
import string, random,time,datetime


def count_time(type):
    def inner():
        start = datetime.datetime.now()
        # time.sleep(2)
        # print(random.sample(string.ascii_letters + string.digits, 6))
        obj = type()
        end = datetime.datetime.now()
        print(end - start)
        return obj
    return inner


@count_time
def rand():
    print(random.sample(string.ascii_letters + string.digits, 6))
    time.sleep(5)


rand()


輸出:
['X', 'm', 'r', '7', 'l', 'D']
0:00:05.000630

例四:

import time,random,string


def count_time(type):
    def inner(*args, **kwargs):
        start = time.time()
        L = type(*args, **kwargs)
        end = time.time()
        print('程序運行時間%s秒' % (end - start))
        return L
    return inner


@count_time
def string_create():
    print(random.sample(string.digits + string.ascii_letters, 6))
    time.sleep(3)


string_create()

輸出:

['O', 'y', 'R', 'V', 'u', '3']
程序運行時間3.000283718109131秒


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章