Python閉包及裝飾器運行原理解析
一、閉包
閉包從形式上來說是在外部函數(shù)中定義內部函數(shù),并且內部函數(shù)引用了外部函數(shù)的變量,此變量叫做自由變量。
或者說是將組成函數(shù)的語句和這些語句的執(zhí)行環(huán)境打包在一起。
閉包滿足的條件:
必須有一個內嵌函數(shù)
內嵌函數(shù)必須使用外部函數(shù)的變量
外部函數(shù)的返回值必須是內嵌函數(shù)
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]
外部函數(shù)closure中有變量value和內部函數(shù)fun,并且內部函數(shù)fun引用了自由變量value,當執(zhí)行cc = closure()時,就產(chǎn)生了一個閉包fun,該閉包持有只有變量value,當函數(shù)closure生命周期結束后,value依然存在,因為它被閉包引用了。
二、裝飾器
裝飾器其實就是閉包的應用,只不過其傳遞的是函數(shù)。
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函數(shù)的元信息丟失,例如__name__等等。
例如demo函數(shù)的__name__會由'demo'變成了'wrapper',這時需要用到functools庫,在wrapper函數(shù)前加上@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!'
例如給任意函數(shù)加上打印時間的功能的裝飾器:
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
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
基于python-opencv3實現(xiàn)圖像顯示和保存操作
這篇文章主要介紹了基于python opencv3的圖像顯示和保存操作方法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值 ,需要的朋友可以參考下2019-06-06
利用Pycharm + Django搭建一個簡單Python Web項目的步驟
這篇文章主要介紹了利用Pycharm + Django搭建一個簡單Python Web項目的步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-10-10
Python的Twisted框架中使用Deferred對象來管理回調函數(shù)
當說起Twisted的異步與非阻塞模式等特性時,回調函數(shù)的使用在其中自然就顯得不可或缺,接下來我們就來看Python的Twisted框架中使用Deferred對象來管理回調函數(shù)的用法.2016-05-05

