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
- Python 中的閉包和自由變數Python變數
- 聊聊Go裡面的閉包Go
- 閉包 pythonPython
- [JavaScript閉包]Javascript閉包的判別,作用和示例JavaScript
- 聊聊 Python 中的閉包Python
- Python和Lua的預設作用域以及閉包Python
- Python閉包和儲存自由變數Python變數
- Python 中的作用域規則和閉包簡析Python
- python中的閉包函式Python函式
- 說說Python中的閉包Python
- Python 中的閉包總結Python
- Python中的閉包總結Python
- Python提高:關於閉包和裝飾器Python
- Python進階之閉包和裝飾器Python
- 深入理解javascript原型和閉包(15)——閉包JavaScript原型
- Python技法4:閉包Python
- python閉包小例子Python
- Python高階--閉包Python
- Python中什麼是閉包?閉包的好處是什麼?Python
- 全面理解Javascript閉包和閉包的幾種寫法及用途JavaScript
- Python: 攜帶狀態的閉包Python
- 聽說你還不理解JavaScript裡的閉包JavaScript
- 理解Python函式閉包Python函式
- python進階(12)閉包Python
- Python深入分享之閉包Python
- python 閉包一例Python
- javascript閉包的理解和例項JavaScript
- [Python小記] 通俗的理解閉包 閉包能幫我們做什麼?Python
- Python 中的閉包與裝飾器Python
- 關於Python閉包的一切Python
- Python閉包的兩個注意事項Python
- python的閉包及裝飾器薦Python
- Python 閉包函式說明Python函式