在了解裝飾器之前,我們先來了解一下閉包,因為裝飾器的本質也是閉包。
閉包:乙個函式定義中引用了函式外定義的變數,並且該函式可以在其定義環境外被執行,這樣乙個函式稱之為閉包。概念比較抽象,我們直接看**:
def outer_func():
loc_list =
def inner_func(name):
print(loc_list)
return inner_func
func = outer_func()
func("a")
func("b")
output:
['a']
['a', 'b']
inner_func函式引用了函式外定義的變數loc_list,並且該函式可以在outer_func外被執行,所以inner_func是乙個閉包。
裝飾器本質也是乙個閉包,裝飾器特別之處在於使用函式作為引數。接下來直接看看裝飾器是如何定義和被呼叫的吧。
如下面的例子:用裝飾器實現任意函式計時和函式峰值記憶體使用的統計;
import time
from functools import wraps
def cdtime(func):
@wraps(func)
def timecount():
starttime = time.time()
result = func()
endtime = time.time()
print(f"函式耗時秒。")
return result
return timecount
import psutil
def cdmum(func):
@wraps(func)
def mumcount():
mum = psutil.virtual_memory()
total = mum.total
result = func()
print(f"函式消耗記憶體位元組。")
return result
return mumcount
@cdtime
@cdmum
def sumn():
sum = 0
for i in range(10000000):
sum += i
return sum
sumn()
如上述**,裝飾器的使用是直接在函式前使用(@ + 函式名)的形式進行呼叫,如@cdtime、@cdmum,而且裝飾器接收呼叫裝飾器的函式名作為引數(sumn),使得其內部可以呼叫外部函式,裝飾器最終返回閉包函式;
這裡還使用了乙個裝飾器@wraps(func),是因為裝飾器返回的是閉包函式,那原函式(sumn)的名稱什麼的都變成了閉包函式,這樣的話不方便程式debug等,所以使用@wraps(func)返回原函式的名稱和位址。
python之閉包和裝飾器
閉包函式必須滿足兩個條件 1.函式內部定義的函式 2.包含對外部作用域而非全域性作用域的引用 如下閉包函式 def callfunc n 1 def show print show n return show s callfunc s 程式在執行時,callfunc 函式返回了內部定義的 show ...
python 裝飾器前之閉包和裝飾器
裝飾器 一,例如 vim yue7.py deffoo print fool foo 執行 root localhost python python yue7.py fool 二,要求 要在上述函式不改變函式呼叫方式的情況下增加 執行的時間。yue6.py import time defshow t...
python裝飾器和閉包
下面幾個部落格有裝飾器的講解,也包含了裝飾器幾種情況的例子,比如說被裝飾的函式帶引數,裝飾器本身帶引數等。理解python中的裝飾器 python裝飾器學習 例子 其實裝飾器跟設計模式中的裝飾器模式基本一樣,就是在已有的函式上新增新的功能,這也是自己對裝飾器的一點簡陋的理解了。下面是自己寫的簡單例子...