按照 python 的程式設計原則,當乙個函式被定義後,如要修改或擴充套件其功能應盡量避免直接修改函式定義的**段,否則該函式在其他地方被呼叫時將無法正常執行。因此,當需要修改或擴充套件已被定義的函式的功能而不希望直接修改其**時,可以使用裝飾器。
先來看乙個簡單的例子:
def func1(function):
print("這裡是執行function()函式之前")
function()
print ("這裡是執行function ()函式之後")
@func1
def func2():
print ("正在執行 function ()函式")
上述**的執行結果如下所示:
>>> def func1(function):
... print("這裡是執行function()函式之前")
... function()
... print ("這裡是執行function()函式之後")
>>> @func1
def func2():
. print ("正在執行 function ()函式")
這裡是執行function()函式之前
正在執行 function()函式
這裡是執行function()函式之後
這裡@func1
等效於func1(func2)
在 python 中一切皆是物件,所以裝飾器本質上是乙個返回函式的高階函式。結合之前介紹的關鍵字引數,可以將乙個函式作為其外部函式的返回值,例如:
def func1(arg = true):
def func2():
print("this is func2() function")
def func3():
print("this is func3() function")
if arg == true:
return func2
else :
return func3
func1()()
上述**的執行結果如下所示。
>>> def func1(arg = true):
... def func2():
... print("this is func2() function")
... def func3():
... print("this is func3() function")
... if arg == true:
... return func2
... else :
... return func3
>>> func1()()
this is func2() function
可以看到,呼叫 func1( ) 時實際上執行了 func2( ) 函式,第二對括號是用以執行 func2( ) 函式的,如果不寫這對括號,將只會得到 func2( ) 函式的引用資訊,如圖下所示。
>>> def func1(arg = true):
... def func2():
... print("this is func2() function")
... def func3():
... print("this is func3() function")
... if arg == true:
... return func2
... else :
... return func3
>>> func1()
.func2 at 0x0000014ed8d663a0>
裝飾器也支援巢狀,巢狀的裝飾器的執行順序是從裡向外,最先呼叫最裡層的裝飾器,最後呼叫最外層的裝飾器,例如:
@a@b
@cdef f()
pass
將按照以下順序執行:
f = a(b(c(f)))
python裝飾器 python 裝飾器詳解
def outer x def inner y return x y return inner print outer 6 5 11 如 所示,在outer函式內,又定義了乙個inner函式,並且inner函式又引用了外部函式outer的變數x,這就是乙個閉包了。在輸出時,outer 6 5 第乙個...
詳解Python裝飾器
裝飾器的難點 在梳理了裝飾器的整個內容之後,我認為難點不是裝飾器本身,而是直接呼叫被裝飾的函式,讓人無法理解背後究竟發生了什麼。一 引出裝飾器概念 引入問題 定義了乙個函式,想在執行時動態的增加功能,又不想改動函式本身的 示例 希望對下列函式呼叫增加log功能,列印出函式呼叫 def f1 x re...
裝飾器詳解(python)
本文將介紹裝飾器的內容,並舉例說明。裝飾器在python中實際上就是乙個函式,這個函式可以在不改變原 其他 函式 和呼叫方式的條件下為原函式新增功能。裝飾器 函式 在結尾返回乙個函式物件。常常用於插入日誌 效能測試 事務處理 快取 許可權校驗等場景。編寫裝飾器函式的原則是 1.不能修改原函式 被裝飾...