Python之裝飾器

2021-08-28 07:21:28 字數 3306 閱讀 7114

內容**主要為總結的《head first python》筆記

python函式修飾符又稱裝飾器,可以為現有函式增加**而不必修改現有函式**。

要編寫乙個修飾符,需要了解四個問題:

1. 如何建立乙個函式

2. 如何把乙個函式作為引數傳遞到另乙個函式

3. 如何從函式返回乙個函式

4. 如何處理任意數量和型別的函式引數

python建立函式通過關鍵字def指定函式名,並列出函式可能有的引數(函式的輸入)。還引入return關鍵字可選,用來向呼叫該函式的**傳回乙個值。

例如: def add_num(a, b):

"""funtion description here """

#single line comments here

return a + b

python直譯器不需要指定函式引數或返回值的型別。任何物件均可作為引數傳送給函式,並且函式允許將任何物件作為返回值傳回。python只檢查是否提供了引數和返回值,從來不會檢查型別。

python中一切皆物件,函式也是物件,有乙個物件id。分析以下例子。

例:>>> msg='hello world'

>>> def hello():

print(msg)

>>> id(msg)

3212332312

>>> id(hello)

3212336659

>>> type(msg)

>>> type(hello)

>>> hello()

hello world

當把hello函式傳遞給id和type, 這裡沒有呼叫hello, 只是把這個函式名作引數傳遞到這兩個函式。

測試該函式如下:

python中,函式**組中的**可以是任意**,包括定義另乙個函式的**,通常稱為巢狀或內部函式。同樣可以從外部函式返回巢狀函式(實際返回的是乙個函式物件)。

def outer():

def inner():

print('this is inner')

print('this is outer, invoking inner.')

inner()

函式inner巢狀在outer函式中。出了在outer的**組中呼叫inner, 不能在其他任何地方呼叫這個函式。innter在outer的區域性作用域。

如果乙個函式很複雜,包含多行**,把一些函式**抽取到乙個巢狀函式中就會很有意義。而且**會更易讀。

更常見的乙個用法是:外圍函式使用return語句返回巢狀函式作為它的返回值修飾符就是採用這種方法來建立

>>> def outer():

def inner():

print('this is inner.')

print('this is outer, returning inner')

return inner #不加()只使用函式名,就會得到函式物件

>>> i=outer()

this is outer, returning inner

>>> type(i)

>>> i()

this is inner.

從例中可看出, 首先將呼叫outer的結果賦給名為i的變數,呼叫i,會執行innter函式的**。

python使用*接收乙個任意的參數列(0個或多個引數)。如下例子:

>>> def myfunc(* args):

for a in args:

print(a, end=' ')

if args:

print()

>>> myfunc()  #不提供引數

>>> myfunc(10) # 乙個引數

10 >>> myfunc(1, 'two', 3, 'four') #引數可以混合多種型別

1 two 3 four 

python還可以直接使用*,當向函式提供乙個列表作為引數,這個列表儘管可能包含多個值,會被處理為一項,即乙個列表引數。為了指示直譯器展開這個列表,把每個列表項作為乙個單獨的引數,呼叫函式時,需要在列表名前面加上*作為字首。

>>> values=[1, 2, 3,4, 5, 6,7]

>>> myfunc(values)

[1, 2, 3, 4, 5, 6, 7] 

>>> myfunc(*values)

1 2 3 4 5 6 7 

python使用**接收任意多個關鍵字引數,即引數字典。

>>> def myfunc2(**kwargs):

for k, v in kwargs.items():

print(k, v, sep='->', end=' ')

if kwargs:

print()

>>> myfunc2(a=10, b=20)

a->10 b->20 

>>> myfunc2()

也可直接使用**。 

>>> values=

>>> myfunc2(**values)

a->1 b->2 c->python 

當然, * 和**可以同時使用。

>>> def myfunc3(*args, ** kwargs):

if args:

for a in args:

print(a, end=' ')

print()

if kwargs:

for k, v in kwargs.items():

print(k, v, sep='->', end=' ')

print()

>>> myfunc3()

>>> myfunc3(1,2,3)

1 2 3 

>>> myfunc3(a=10, b=20)

a->10 b->20 

>>> myfunc3(1,2,3,a=10, b=20)

1 2 3 

a->10 b->20 

要建立乙個函式修飾符需要知道:

1. 修飾符是乙個函式

2. 修飾符取被修飾函式作為引數

3. 修飾符返回乙個新函式

4. 修飾符維護被修飾函式的簽名

修飾符需要確保它返回的函式與被修飾函式有相同的引數(個數和型別都相同)。函式引數的個數和型別稱為其簽名。

舉例,web相關的很多函式的前提是需要確保頁面已登陸。所以需要建立判斷是否登陸的修飾符。

最後乙個問題是函式如何向直譯器標識自己的身份。python標準庫提供了乙個模組來處理這些。只需匯入模組functools, 然後呼叫wraps函式即可。

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

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

python 找到裝飾器 Python之裝飾器

裝飾器本質上就是乙個python函式,他可以讓其他函式在不需要做任何 變動的前提下,增加額外的功能,裝飾器的返回值也是乙個函式物件。裝飾器的作用 在不改變原函式及原函式的執行的情況下,為原函式增加一些額外的功能,比如列印日誌 執行時間,登入認證等等。乙個簡單的裝飾器 import time def ...

Python之裝飾器

裝飾器就是乙個以函式作為引數並返回乙個替換函式的可執行函式 即裝飾器是乙個函式,其引數為函式,返回值也為函式 可理解為對函式的功能進行拓展,所以叫裝飾 outer為裝飾器,效果為給被裝飾函式返回值結果加負號 defouter fun definner x return fun x return in...