python語言特性之裝飾器

2021-08-28 18:32:04 字數 2139 閱讀 1627

首先,python裝飾器的作用是:在不改變原有函式實現的前提下,給此函式增加一些額外的功能(在原有函式呼叫之前或者呼叫之後),好像給原有函式加上了乙個裝飾的殼子

通過乙個例子解釋python裝飾器:

# -*- coding:utf8 -*-

def w1(func):

def inner(*args,**kwargs):

print 'w1'

func(*args,**kwargs)

print func

return inner

def w2(func):

print func

def inner(*args,**kwargs):

print 'w2'

func(*args,**kwargs)

return inner

def w3(func):

print func

def inner(*args,**kwargs):

print 'w3'

func(*args,**kwargs)

return inner

@w3@w2

@w1def f1(arg1,arg2,arg3):

print 'f1'

f1(1,2,3)

以上是python多個裝飾器使用的例子,目的是為了更好說明裝飾器、以及裝飾器鏈的使用,裝飾器函式的呼叫順序等等。

那麼,在使用三個裝飾器裝飾f1函式,會怎麼執行呢,結果如何呢?

首先需要明確乙個概念,函式和函式的呼叫

第二個概念:語法糖。(@函式名來裝飾函式名只舉乙個例子:

@w1

def f1(arg1,arg2,arg3):

print 'f1'

以上**相當於

def f1(arg1,arg2,arg3):

print 'f1'

f1 = w1(f1)

注意:f1 = w1(f1) 中,作為引數的f1和返回的f1 已經不是同乙個f1了。好,先看看執行結果:

疑問1:w1 w2 w3三個裝飾器的執行順序是怎麼樣的?

疑問2:為什麼呼叫了三次裝飾器,只呼叫了一次f1,不應該每呼叫一次w就呼叫一次f1嗎?

第乙個疑問:多個裝飾器的呼叫順序是自下往上,但是執行時的執行順序是自上往下!其實只需要記住呼叫順序是自下往上,執行順序可以從呼叫順序推出來!同理第二個疑問也可以通過相同辦法推出來。

根據以上語法糖的解釋,根據自下往上的呼叫順序,函式裝飾器還可以表示為以下方式:

def f1(arg1,arg2,arg3):

print 'f1'

f1 = w1(f1) #1 把以上f1作為引數傳給w1,再把函式返回值傳回給f1(相當於給f1賦了新值,新的值為w1的返回值inner)

f1 = w2(f1) #2 把inner(注意,此時f1已經是w1的返回值inner)作為引數傳給w2,並且給f1重新賦新值

f1 = w3(f1) #3 把w2的返回值inner作為引數傳給f1,並且給f1重新賦值(w3的返回值inner)

為了更加清楚說明,我們翻譯如下:

f1 = w1(最初f1)

f1 = w2(w1函式返回值inner)

f1 = w3(w2函式返回值inner)

此時,我們呼叫函式f1(1,2,3),其實就是呼叫了w3裡面的inner函式。但是給w3傳的引數是w2的返回值inner。等呼叫到w3中func(*args,**kwargs)函式的時候,其實是呼叫了w2的內層函式inner。以此類推,直到呼叫w1內部的func(*args,**kwargs)函式的時候,才是呼叫的最初的f1函式,所以,其實f1函式只呼叫了一次,而且是按照w3、w2、w1、f1的順序執行。

以上就是python裝飾器的使用。

Python高階特性之裝飾器

裝飾器 定義乙個裝飾函式,函式必須返回乙個閉包 閉包就是執行時所需要的外部變數 函式物件,關於閉包的具體介紹,可參考函式,並且被裝飾的函式會被python自動傳遞給裝飾函式,作為裝飾函式的乙個引數。裝飾器的具體定義 1 把要裝飾的方法作為輸入引數 2 在函式體內可以進行任意的操作 可以想象其中會有很...

python高階特性(裝飾器)

裝飾器本質上是乙個函式,該函式用來處理其他函式,它可以讓其他函式在不需要修改 的 前提下增加額外的功能,裝飾器的返回值也是乙個函式物件。它經常用於有切面需求的場景,比如 插入日誌 效能測試 事務處理 快取 許可權校驗等應用場景。首先我們先了解以下通用裝飾器的框架,幫助我們更好地理解裝飾器的用法 de...

python裝飾器介紹 Python之裝飾器簡介

python函式式程式設計之裝飾器 1.開放封閉原則 簡單來說,就是對擴充套件開放,對修改封閉。在物件導向的程式設計方式中,經常會定義各種函式。乙個函式的使用分為定義階段和使用階段,乙個函式定義完成以後,可能會在很多位置被呼叫。這意味著如果函式的定義階段 被修改,受到影響的地方就會有很多,此時很容易...