1. 程式人生 > >python 閉包 ,裝飾器

python 閉包 ,裝飾器

 

 

#_author:'DJS'
#date:2018-12-12
import time
##閉包就是兩個函式組成,裡面的函式用到外面函式的變數值再加上裡面函式的值,那一個坨空間,就是閉包。
##能當做實參進行傳遞,並且能傳遞功能和資料。
def line_6(k,b):
    x = 200
    def create_y(x):
        nonlocal x #修改閉包外面的值,用nonlocal.
        print(k*x+b)
    return create_y #返回一個函式名,即是函式的引用,line_6函式的返回值就是一個函式的引用
#返回值是一個函式的引用,說明它還可以呼叫一個函式。閉包就是裡面巢狀的函式,可以用外面函式的
#變數,就是一個函式幹了兩個函式的事情。把我一個函式名作為實參傳遞,得到的是這個函式引用
#即是函式的程式碼並沒有資料,但是閉包可以實現傳遞一個函式名,還能傳遞這個函式的資料。
#函式和閉包的區別:函式就是一坨程式碼,他不會把資料傳遞過去,但是閉包擁有函式的功能還能傳遞資料。
#函式,匿名函式,閉包,物件,當做實參時,的區別。
#1.匿名函式能夠完成基本的簡單功能,傳遞是這個函式的引用,只有功能
#2.普通函式能夠完成較為複雜的功能,傳遞是這個函式的引用,只有功能
#3.閉包能夠完成較為複雜的功能,傳遞是這個閉包中的函式以及資料,因此傳遞是功能加資料
#4.物件能夠完成最為複雜的功能,傳遞是很多資料+很多功能,因此傳遞是功能+資料
line_6_1 = line_6(1,2) #這裡相當於建立了一個閉包
line_6_1(0)
line_6_1(1)
line_6_1(2)
line_6_2 = line_6(11,22)
line_6_2(0)
line_6_2(1)
line_6_2(2)

###裝飾器
def set_func(func):#set_func()函式的主要作用是傳遞變數,即傳遞資料。還有下面的返回值
#執行set_func()函式得到的是一個返回值,這個返回值裡面還攜帶著一個變數(函式引用)。
    def call_func(*args,**kwargs):#接收的時候用不固定長引數來接收#被裝飾的函式有引數,這裡也要有引數 #執行set_func函式的時候,這個函式不會執行,他是一個函式,並沒有呼叫他
#執行test1()的時候才呼叫這個函式,然後再呼叫下面那個func(),func()就是下面那個test1
#函式,func變數是指向test1的。把一個函式名當做實參傳遞,也要呼叫這個函式,這個函式才能執行
        star_time = time.time()
        # print("---這是許可權驗證1--")
        # print("--這是許可權驗證2--")
        func(*args,**kwargs)#傳遞的時候就用不固定長的引數來傳遞 #被裝飾的函式有引數,這裡也要有引數
        stop_time = time.time()
        return func(*args,**kwargs) #加return和不固定長引數就是通用裝飾器了
        print("執行的時間戳%f" %(stop_time-star_time))
    return call_func
#@set_func #先執行裝飾器的程式碼,再執行下面函式的程式碼
#在函式上面新增@set_func等價於test1 = set_func(test1)這句話
#裝飾器是在函式執行之前執行。
@set_func #裝飾器在沒有呼叫函式之前已經裝飾好了
def test1(num):
    for i in range(100000):
        pass

#test1 = set_func(test1) #這裡把text1的函式當做實參,改變test1的指向,讓它指向set_func函式的
#返回值
#裝飾器裝一個函式線當於建立了一個閉包,閉包外函式的變數指向被裝飾的函式。裝飾器在沒有呼叫函式之前已經裝飾器
test1(100)