Python 裝飾器歸納總結

2021-07-25 14:49:50 字數 3895 閱讀 4468

實際應用中裝飾器沒少用,像flask的路由功能,都是用裝飾器來掛上去的,不過平時裝飾器都是看的網上的文章然後在用,自己沒總結過

這次單獨寫一篇筆記,加深印象

先簡單講一下我理解的裝飾器的兩大特點

1:在不用修改原本函式的情況下,對原來函式的輸出結果進行新增功能

2:裝飾器是乙個高階函式,他的返回值,是乙個函式

首先來看個普通函式

def current_time():

print ('2016.12.25')

f=current_time

f()print (current_time.__name__)

這是乙個列印當前日期的函式,最後還會列印出函式名字

2016.12.25

current_time

可以看到,能列印出函式名字,是因為我們在呼叫的時候,手工列印了出來,如果你要自動地列印,那你就要修改原本的函式了

這樣簡單的函式改改還不是問題,如果你在乙個大專案裡面涉及到很多要改的地方,估計就要吐了。

所以,裝飾器就可以提現他的作用了

def ******(f):

def inside():

print ('here in decorator for function %s'% f.__name__)

return f

return inside

#呼叫方法1: 這個是最直接的方法,用@語法糖,這個的作用,和呼叫方法3的原理是一模一樣的,將本體函式current_time傳給******

@******

def current_time():

print ('now')

current_time()

#呼叫方法2: 這個需要理解下******(current_time)了以後,就相當於已經取到返回的inside了,如果你需要執行的話,就在後面再加一對()

def current_time():

print ('now')

******(current_time)()

#呼叫方法3 : 裝飾器的基本原理,將本體函式以引數的方式傳遞給裝飾器

def current_time():

print ('now')

current_time=******(current_time)

current_time()

這樣乙個最簡單的裝飾器就完成了,當你呼叫current他的輸出結果是

def current_time(x,y):

return x+y

def decorator(f):

return f(*args,**kw)*3

@decorator

def current_time(x,y):

return (x+y)

print (current_time(1,2))

可以看到,decorator就是我們裝飾器的名字了,他的引數是你需要加強的函式(以下稱為本體函式

他的作用是:將本體函式的結果,乘以3

我們來看一下效果

這樣,你原來輸入的引數1和2,相加結果是3,但是經過裝飾器以後,結果就是3倍了。

的。這裡需要特別記住:@這個語法,在這種情況下,只能相當於,將本體函式(這乙個引數)傳入裝飾器函式,沒法附帶其他的內容

比如,你沒法使用  @decorator( 'test_text' ) 這樣的語法,他會提示引數錯誤的。

當然,你如果強行用current_time = decorator(current_time , 'test_text' )這樣的寫法,也是可以達到同時傳入其他引數的目的

但是,這寫法的繁瑣程度和不用裝飾器,沒啥區別。

所以,我們引入了帶引數的裝飾器

平時用的最多的就是flask的路由裝飾器了

比如最簡單的flask路由

def index():

return 'hello world'

那要實現這樣的功能,如何修改裝飾器呢?

這就需要再包括一層裝飾器了

def top(text):

def decorator(f):

print (text+' of top')

return f(*args,**kw)*3

return decorator

@top('text for test')

def current_time(x,y):

return (x+y)

print (current_time(1,2))

這樣,你的裝飾器就可以隨意新增你想要加的內容了

效果看下

e:\atry>python de.py

text for test of top

9

這樣的語句的簡單理解寫法是 current_time = top('text for test')(current_time)也就是,先執行 top('text for test'),他返回decorator函式,然後,decorator函式再加上後面的(current_time)作為引數傳入這裡要額外提一下,這樣裝飾器,他的本體引數的__name__屬性已改變,如果碰到一些和函式名字撤上關係的功能時,會引發錯誤

先看名字被改變的測試

print (current_time.__name__)import functoolsdef current_time(x,y):

return x+y

def top(text):

def decorator(f):

@functools.wraps(f)

print (text+' of top')

return f(*args,**kw)*3

return decorator

@top('text for test')

def current_time(x,y):

return (x+y)

print (current_time(1,2))

print (current_time.__name__)

這樣,做出來的程式,他的名字就不會被修改了

有時候你會看到,乙個函式上面掛了好幾個裝飾器,那他們是否有先後順序呢?

肯定有的,我們來看看多重裝飾器是從上往下還是從下往上開始執行

def add_before(f):

print (f()+' add_before decorator')

return f()+' add_before decorator'

def add_later(f):

# print (f()+' add_later decorator')

return f()+' add_later decorator'

@add_before

@add_later

def test():

return 'here in test'

test()

通過下面的效果圖,你可以看到,他是先被add_later 裝飾器進行了作用,再進行add_before裝飾器作用

也就是從最靠近本體函式的地方開始起裝飾器作用

這樣,裝飾器基本的概念就完全了,其他的具體應用,也是基於這些原理之上的。

Python 裝飾器總結

目錄閉包 裝飾器簡單裝飾器 修飾帶參函式的裝飾器 本身帶引數的裝飾器 類裝飾器 裝飾器缺點 裝飾器用途 說到裝飾器就不能忽略閉包,下面先介紹一下閉包的概念 在一些語言中,在函式中可以 巢狀 定義另乙個函式時,如果內部的函式引用了外部的函式的變數,則可能產生閉包。閉包可以用來在乙個函式與一組 私有 變...

Python 裝飾器總結

目錄 閉包裝飾器 簡單裝飾器 修飾帶參函式的裝飾器 本身帶引數的裝飾器 類裝飾器 裝飾器缺點 裝飾器用途 說到裝飾器就不能忽略閉包,下面先介紹一下閉包的概念 在一些語言中,在函式中可以 巢狀 定義另乙個函式時,如果內部的函式引用了外部的函式的變數,則可能產生閉包。閉包可以用來在乙個函式與一組 私有 ...

python 裝飾器 學習總結

有點類似函式的目的 函式的目的就是當你有1w個 塊要新增相同的功能時,只需要呼叫已經寫過一次的函式就好,而不是要寫1w次同樣的 當你有1w個函式要新增相同的功能時,只需要呼叫已經寫過一次的修飾器就好 還有就是當你的程式很龐大時,想要給你的程式中的某個模組加上新的功能,不可能說直接修改源 因為說不定修...