python閉包及裝飾器執行原理解析
阿新 • • 發佈:2020-06-17
一、閉包
閉包從形式上來說是在外部函式中定義內部函式,並且內部函式引用了外部函式的變數,此變數叫做自由變數。
或者說是將組成函式的語句和這些語句的執行環境打包在一起。
閉包滿足的條件:
必須有一個內嵌函式
內嵌函式必須使用外部函式的變數
外部函式的返回值必須是內嵌函式
def closure(): value = [] def fun(tmp): value.append(tmp) return value return fun cc = closure() cc(0) #[0] 等同於closure(fun(0)) cc(1) #[0,1] cc(2) #[0,1,2]
外部函式closure中有變數value和內部函式fun,並且內部函式fun引用了自由變數value,當執行cc = closure()時,就產生了一個閉包fun,該閉包持有隻有變數value,當函式closure生命週期結束後,value依然存在,因為它被閉包引用了。
二、裝飾器
裝飾器其實就是閉包的應用,只不過其傳遞的是函式。
def add_time(fun): def wrapper(): print('time: 12:00') return fun() return wrapper def add_format(fun): def wrapper(): print('\n') return fun() return wrapper @add_format #等同於demo = add_format(add_time(demo)) @add_time #等同於 demo = add_time(demo) def demo(): return 'hello world!'
另外,裝飾器會將demo函式的元資訊丟失,例如__name__等等。
例如demo函式的__name__會由'demo'變成了'wrapper',這時需要用到functools庫,在wrapper函式前加上@functools.wraps(fun):
import functools def add_time(fun): @functools.wraps(fun) def wrapper(): print('time: 12:00') return fun() return wrapper def add_format(fun): @functools.wraps(fun) def wrapper(): print('\n') return fun() return wrapper @add_format #等同於demo = add_format(add_time(demo)) @add_time #等同於 demo = add_time(demo) def demo(): return 'hello world!'
例如給任意函式加上列印時間的功能的裝飾器:
def metric(fn): start=time.time() @functools.wraps(fn) def wrapper(*args,**kw): end=time.time() print('%s executed in %s ms' % (fn.__name__,start-end)) return fn(*args,**kw) return wrapper
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。