python 裝飾器

python裝飾器的主要用途就是在不修改源代碼以及不修改調用方式的狀況下給本來的代碼增長新的功能。python

舉個栗子:你的眼睛近視一千度,這個時候在不給你作任何改動的狀況下戴個眼鏡你就能夠看清世界了,眼鏡就是你的裝飾器,這裏咱們要學會怎麼給「近視」的代碼加一個「眼鏡」。閉包

但是.... 提及來簡單...  怎麼實現...函數

首先寫個函數this

import time #導入時間模塊
def func():
time.sleep(
1)
print("run the func")

func() #調用函數

run the func #
運行結果

無參裝飾器

如今若是咱們想給咱們的代碼加上一個統計運行時間的功能,用裝飾器的方式怎麼加??spa

import time

def f1(parameter): #2
def f2(*args,**kwargs): #3
start_time=time.time()
parameter(*args,**kwargs)
stop_time=time.time()
print("the func run time is %s" %(stop_time-start_time))
return f2

@f1 #1
def func(): #源代碼並無變
time.sleep(
1)
print("run the func")

func()

run the func #執行結果 the func run time is 1.0000569820404053

 

#1: @f1 爲裝飾器的默認語法,,裝飾器傳的參數是正下方函數的名字,調用結果在從新賦值給下面的函數名字,實際上這句的意思就是 func=f1(func),賦值以後實際上只是一個內存地址,因此調用的時候要加()運行,也就是func()。
#2: 裝飾器是利用嵌套函數+閉包函數的方式實現,在這裏f1(parameter) 中parameter在這裏實際上傳的參數就是func,而這個f1函數的代碼僅僅就是定義了一個f2函數以及return f2的內存地址,so實際上f1 就是f2,只不過在f2 裏面引用了f1傳進來的參數,接下來咱們看f2函數。
    閉包函數下面有個簡單的介紹
#3: f2(*args,**kwargs) 這裏*args和**kwargs包含了全部能夠傳遞進來的參數,在f2函數內寫咱們須要增長的功能,而後把對應的parameter函數(注意這裏parameter其實是func函數)放在咱們須要的位置,函數前面寫上時間,後面寫上時間,最後用運算方式相減,就獲得了咱們想要的運行時間。

有參裝飾器

但是若是咱們的源代碼有傳值的話怎麼辦,上面的裝飾器咱們用就不夠了。內存

再次寫個須要傳參的函數:作用域

def func(x):
  time.sleep(1)
print("this parameter is %s" %x)

func(
1)

this parameter is 1 #運行結果

這個若是統計時間應該怎麼統計??讓咱們把剛纔無參函數的裝飾器拿過來,稍微改一下。import

import time
def f3(par):
def f1(parameter):
def f2(*args,**kwargs):
start_time=time.time()
parameter(*args,**kwargs)
stop_time=time.time()
print("the func run time is %s" %(stop_time-start_time))
return f2
return f1

@f3(1)
def func(x):
time.sleep(
1)
print("this parameter is %s" %x)

func(
1)

this parameter is 1 #運行結果 the func run time is 1.0000569820404053

能夠看到 f1函數和f2函數並無改動,只是在外面多嵌套了一層函數f3,可是裝飾器的調用方式相比有點小小的區別,這裏裝飾器使用的時候是@f3(1),這裏的這個1就是給咱們的源代碼傳的值。這就是有參函數的使用方式,接下來咱們就能夠根據外面傳進來的值作咱們相對應的代碼處理。變量

 


閉包函數:語法

內置變量:只有打開python 就能夠用的,寫入到python語言內部,定義好的變量,例如print函數咱們用的時候能夠直接調用。

全局變量:就是咱們在py文件中頂頭寫的變量或者函數,好比x=1,做用域是當前py文件。

局部變量:在函數內部定義的,做用域是當前函數。

咱們在使用一個變量的時候查找方式,如今局部變量找,若是沒有就找全局變量,若是在沒有就找內置變量,若是尚未就會給你提示錯誤了,首先找到哪一個,就返回哪一個給你調用,這也是咱們設置變量的時候爲何不能用關鍵字定義,由於一旦定義了就會覆蓋內置變量,接下來若是須要使用就會報錯,

閉包函數定義:內部函數的代碼,包含對外部函數的引用,但必定不是對全局做用域的引用。(說明閉包函數最起碼會嵌套兩層)

閉包函數例子:

x=1
def closure_1():
x=
6
def closure_2():
print(x)
return closure_2g=closure_1()g()6 #執行結果,打印的是closure_1內部定義的x變量,這裏打印的就是局部變量,這是一個正確的閉包函數,若是打印結果是全局變量定義的x=1,那確定是哪裏錯了,這就不是一個閉包函數。
相關文章
相關標籤/搜索