2019-07-11 閉包函數和裝飾器

1、閉包函數閉包

  定義:定義在內部的函數引用外部函數的名字(變量)叫作閉包函數ide

  要打印的是inner函數的x,由於這個函數裏面沒有定義x的值,因此找上一層的局部變量x = 111。執行代碼,outter函數被調用,返回值爲inner,用變量res接收,因此res = inner,下面再用res(),就是inner(),調用inner函數,執行裏面代碼,打印結果爲111函數

def outter():
    x = 111
    def inner():
        print(x)
    return inner
res = outter()  # res就是inner函數內存地址
res()    #111

  給函數體傳值的兩種方式:工具

    1.函數調用時候直接傳參spa

def index1(username):
    print(username)
res = index1('aa')      #aa

    2.閉包傳參3d

  這個和剛開始定義的閉包函數同樣只不過是把變量x,y放在outter函數裏面當形參,在調用的時候傳實參code

def outter(x,y):
    # x = 1
    # y = 40
    def my_max():
        if x > y:
            return x
        return y
    return my_max
res1 = outter(1,40)  # res就是my_max函數的內存地址
print(res1())    #40

 

2、裝飾器對象

  定義:給被裝飾的對象添加新的功能的一個工具。  目的:更方便的使用新添加的新功能blog

  裝飾器(可調用對象)必須遵照的兩個原則:內存

    1.不可改變被裝飾對象的代碼

    2.不可改變 被裝飾對象的調用方式(假如調用方式是idnex(),使用裝飾器以後也是這種調用方式)

  

  簡單版本:

  在原始函數index函數上加一個時間計算功能,最後也是調用了index(),沒有違反裝飾器的兩個原則。運行函數先到outter調用,裏面傳一個參數index(這個是最原始的index函數的內存地址),而後返回get_time,用變量index接收。index()其實就是調用get_time函數。執行裏面代碼,func()就是以前傳的func參數,index()調用。

import time
def index():
    time.sleep(3)
    print('睡醒了')

def outter(func):  # func = 最原始的index函數的內存地址
    def get_time():
        start = time.time()
        func()  # func = index函數的內存地址() 直接調用
        end = time.time()
        print('index run time:%s'%(end-start))
    return get_time
index = outter(index)  # outter(最原始的index函數內存地址)
# index指向get_time函數的內存地址
index()   #睡醒了

  升級版本:(被裝飾的函數須要參數,以前的用法須要在get_time裏面的func()寫參數,才能使用正確。統一參數寫法:*args,**kwargs)

import time
def index():
    time.sleep(3)
    print('澳門最大線上賭場開業啦 性感tank在線發牌!')
    return 'index'
# res1 = index()

def login(name):
    time.sleep(1)
    print('%s is sb'%name)
    return 'login'
# res = login('egon')

def outter(func):  # func = 最原始的login函數的內存地址
    def get_time(*args, **kwargs):  # args = ('egon',) kwargs = {}
        start = time.time()
        res = func(*args, **kwargs)  # 最原始的login函數的內存地址() 直接調用  func('egon')
        end = time.time()
        print('func run time:%s'%(end-start))
        return res
    return get_time
login = outter(login)  # outter(最原始的login函數的內存地址)
res = login('egon')
print(res)
index = outter(index)
res1 = index()
print(res1)
代碼

  這樣設置以後能夠接受任意參數的函數。

 3、裝飾器語法糖

  語法糖在書寫的時候應該與被裝飾器牢牢挨着,二者之間不要有空。把裝飾器賦值給緊挨這的的可調用對象,而且把緊挨着的函數名當作參數傳遞到裝飾器中

 

4、多個裝飾器一塊兒使用

   注意:裝飾器裝飾順序:從下往上

        裝飾器執行效率:從上往下

 

 

相關文章
相關標籤/搜索