詳解Python裝飾器

2021-08-02 18:21:08 字數 2456 閱讀 2402

裝飾器的難點:在梳理了裝飾器的整個內容之後,我認為難點不是裝飾器本身,而是直接呼叫被裝飾的函式,讓人無法理解背後究竟發生了什麼。

一、引出裝飾器概念

引入問題:  定義了乙個函式,想在執行時動態的增加功能,又不想改動函式本身的**?

示例:

希望對下列函式呼叫增加log功能,列印出函式呼叫:

def f1(x): return x*2

def f2(x): return x*x

def f3(x): return x*x*x

方法一:直接修改原函式的定義

def f1(x): 

print("call f1")

return x*2

def f2(x):

print("call f2")

return x*x

def f3(x):

print("call f3")

return x*x*x

方法二:通過高階函式返回新函式

思考:高階函式

(1)、接受函式作為引數

(2)、返回函式

(3)、因此:通過接收乙個函式,內部對其包裝,然後返回乙個新函式,這樣子動態的增強函式功能

def f1(x): return x*2

def new_fun(f):

""" 裝飾器函式 """

def fun(x):

print("call " + f.__name__)

return f(x)

return fun

new_fun(f1)(10)

方法三:真正的裝飾器

python

內建的 @ 語法就是為了簡化裝飾器的使用。

@new_fun代表的意思:呼叫new_fun函式,引數是@所在行下面的函式

@new_fun

def f1(x): return x*2

@new_fun

def f2(x): return x*x

@new_fun

def f3(x): return x*x*x

f1(10)

f2(100)

f3(1000)

f1(10)的呼叫方式等價於new_fun(f1)(10), new_fun(f1)返回的是裝飾器內部函式fun,即fun(10). 整個功能的完成被分成三部分:裝飾器函式執行,返回裝飾器內部函式;裝飾器內部函式執行,執行logging功能;在執行內部函式的同時或者執行完內部函式之後,執行被裝飾函式f(x)。因此我們也容易看出整個裝飾器就是三部分:裝飾器函式,裝飾器內部函式,被裝飾函式。

三、裝飾器作用:可以極大簡化**,避免每個函式編寫重複性的**

(1)、列印日誌:@log,如本文所舉的例子

(2)、檢測效能:@performance,例如機器學習訓練模型,監測多個模型,多個函式執行時間。

四、裝飾器函式三步走

(1)、定義自己先要執行的函式

(2)、定義裝飾器函式

def new_fun(要執行的函式f):

def fun(要執行的函式的引數x):

新增函式功能

return f(x)

return fun

(3)、裝飾器進行修飾

# -*- coding: utf-8 -*-

# 裝飾器監測函式的呼叫和效能

def print_log(f):

""" 裝飾器函式: 監測函式的呼叫 """

def fun(x):

print(f.__name__ + " is called.")

# 可以不返回, 直接在此處執行f(x)

return f(x)

return fun

@print_log

def sort_fun(num_list):

""" 排序函式 """

return sorted(num_list)

if __name__ == "__main__":

num_list = sort_fun(list(range(100))*100)

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裝飾器詳解 python裝飾器詳解

按照 python 的程式設計原則,當乙個函式被定義後,如要修改或擴充套件其功能應盡量避免直接修改函式定義的 段,否則該函式在其他地方被呼叫時將無法正常執行。因此,當需要修改或擴充套件已被定義的函式的功能而不希望直接修改其 時,可以使用裝飾器。先來看乙個簡單的例子 def func1 functio...

裝飾器詳解(python)

本文將介紹裝飾器的內容,並舉例說明。裝飾器在python中實際上就是乙個函式,這個函式可以在不改變原 其他 函式 和呼叫方式的條件下為原函式新增功能。裝飾器 函式 在結尾返回乙個函式物件。常常用於插入日誌 效能測試 事務處理 快取 許可權校驗等場景。編寫裝飾器函式的原則是 1.不能修改原函式 被裝飾...