Python裡的閉包和AOP
習慣了寫Java和JS程式碼,突然換成Python還真不習慣,最近在書上看到一段挺有意思的Python程式碼,才真心感覺到Python長盛不衰的價值。在很多語言裡,如果在一個內部函式裡,對外部作用域(但不是全域性作用域)的變數進行引用,那麼內部函式就被認為是閉包(closure)。定義在外部函式內的但由內部函式引用或者使用的變數被稱為自由變數。閉包的詞法變數不屬於全域性或者區域性作用域,而屬於一種“流量”的作用域。
先介紹一種語法,Python有種叫函式裝飾器的東西,這是一種特殊的函式,因為它接受函式物件為引數,對其進行封裝加工並返回。舉個簡單的例子:
@deco(deco_args)
def foo(): pass
#相當於:foo = deco(deco_args) (foo)
裝飾器封裝了foo,並返回新版本的foo。這其實就是一種閉包的用法,因為無論在deco函式中定義了那些變數,當呼叫新版本foo的時候都可以訪問到它們,那些變數並不隨著deco函式的執行結束返回而銷燬,而是繼續存活在“流量”空間裡等待被啟用。如果要問這有什麼作用?最容易理解的就是對比Java裡的AOP概念,在不改變原始碼的情況下,織入切面,新增統一的邏輯:打日誌、效能指標記錄、統一事務管理等等。而在python裡面,AOP居然如此之簡單,通過函式裝飾器和閉包的特性就可以輕易解決。下面這個例子,就是對閉包強大特性的一個體現:(給方法hello新增執行時間的分析,不改動原方法hello的程式碼)
#!usr/bin/env python
from time import time
def logged(when):
def log(f, *args, **kargs):
print '''Called:
function: %s
args: %r
kargs: %r''' % (f,args,kargs)
def pre_logged(f):
def wrapper(*args, **kargs):
log(f, *args, **kargs)
return f(*args, **kargs)
return wrapper
def post_logged(f):
def wrapper(*args, **kargs):
now = time()
try:
return f(*args, **kargs)
finally:
log(f, *args, **kargs)
print "time delta: %s" % (time()-now)
return wrapper
try:
return {"pre": pre_logged, "post": post_logged}[when]
except:
raise ValueError(e), 'must be "pre" or "post"'
@logged("post")
def hello(name):
print "Hello, ", name
hello("World")
可以看到只是簡單的在hello方法前新增了一個函式裝飾器,就可以讓hello的呼叫具有分析執行時間的特性,成功的織入切面!我這的執行結果是:
Hello, World
Called:
function: <function hello at 0x10755aa28>
args: ('World',)
kargs: {}
time delta: 3.88622283936e-05
相關文章
- python的裝飾器和閉包Python
- Python 中的閉包和自由變數Python變數
- Python_閉包和裝飾器Python
- Python閉包和儲存自由變數Python變數
- 聊聊Go裡面的閉包Go
- [JavaScript閉包]Javascript閉包的判別,作用和示例JavaScript
- Python提高:關於閉包和裝飾器Python
- Python進階之閉包和裝飾器Python
- Python高階--閉包Python
- Python技法4:閉包Python
- Python中什麼是閉包?閉包的好處是什麼?Python
- Python深入分享之閉包Python
- python進階(12)閉包Python
- 理解Python函式閉包Python函式
- [Python小記] 通俗的理解閉包 閉包能幫我們做什麼?Python
- 關於Python閉包的一切Python
- Python 中的閉包與裝飾器Python
- python閉包 - 理解與應用Python
- Python閉包與裝飾器Python
- Python 閉包函式說明Python函式
- python closure閉包 lambda表示式Python
- Python學習筆記 - 閉包Python筆記
- 【python】閉包與裝飾器Python
- 聽說你還不理解JavaScript裡的閉包JavaScript
- Python如何訪問閉包中的變數Python變數
- 草根學Python(十五) 閉包(解決一個需求瞭解閉包流程)Python
- JavaScript 中的閉包和事件委託JavaScript事件
- python_August(閉包、裝飾器)Python
- python高階-閉包-裝飾器Python
- Python基礎之閉包函式Python函式
- Python:從閉包到裝飾器Python
- Python學習之路26-函式裝飾器和閉包Python函式
- JavaScript之作用域和閉包JavaScript
- python下載的庫包放哪裡Python
- 什麼是閉包,閉包的優缺點?
- Python基礎(五)——閉包與lambda的結合Python
- 閉包的起源
- JavaScript 的閉包JavaScript