標籤:
把函數作為參數傳入,這樣的函數稱為高階函數,函數式編程就是指這種高度抽象的編程範式
lambda
(lambda x: x*2)(3)
裝飾器 decorator
裝飾器是一個很著名的設計模式,經常被用於有切面需求的情境,較為經典的有插入日誌、效能測試、交易處理, Web許可權校正, Cache等。例如記錄日誌,需要對某些函數進行記錄。笨的辦法,每個函數加入代碼,如果代碼變了,就悲催了。裝飾器的辦法,定義一個專門日誌記錄的裝飾器,對需要的函數進行裝飾,搞定。
優點:抽離出大量函數中與函數功能本身無關的雷同代碼並繼續重用。即,可以將函數“修飾”為完全不同的行為,可以有效將商務邏輯正交分解,如用於將許可權和身分識別驗證從業務中獨立出來。
概括的講,裝飾器的作用就是為已經存在的對象添加額外的功能。
本質上,decorator就是一個返回函數的高階函數
def log(func): def wrapper(*args, **kw): print ‘call %s():‘ % func.__name__ return func(*args, **kw) return wrapper @log #相當於now = log(now) def now(): print ‘2013-12-25‘ ------------------------------ >>> now() call now(): 2013-12-25 #如果decorator本身需要傳入參數,那就需要編寫一個返回decorator的高階函數,寫出來會更複雜。比如,要自訂log的文本: def log(text): def decorator(func): def wrapper(*args, **kw): print ‘%s %s():‘ % (text, func.__name__) return func(*args, **kw) return wrapper return decorator @log(‘execute‘) #相當於now = log(‘execute‘)(now) def now(): print ‘2013-12-25‘ ------------------------------ >>> now() execute now()
有一些細節需要注意。裝飾後(函數名等函數屬性會發生改變)。所以寫一個裝飾器的時候,最好在實現之前加上functools模組的warp,它能保留原有函數的名稱和docstring.
import functools def log(func): @functools.wraps(func) def wrapper(*args, **kw): print ‘call %s():‘ % func.__name__ return func(*args, **kw) return wrapper @log def now(): print ‘2013-12-25‘
python內建map, reduce, filter, sorted函數的用法
map(f, [x1, x2, x3, x4]) = [f(x1), f(x2), f(x3), f(x4)] map(lambda x,y: x+y, [1,1,1], [2,3,4]) reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4) filter(f, [1, 2, 4, 5, 6, 9, 10, 15]) #篩選符合f的資料,返回list sorted([x1, x2, x3, x4], f) #以f的形式進行排序,返回list def str2int(s): def fn(x, y): return x * 10 + y def char2num(s): return {‘0‘: 0, ‘1‘: 1, ‘2‘: 2, ‘3‘: 3, ‘4‘: 4, ‘5‘: 5, ‘6‘: 6, ‘7‘: 7, ‘8‘: 8, ‘9‘: 9}[s] return reduce(fn, map(char2num, s))
#用lambda函數進一步簡化 def char2num(s): return {‘0‘: 0, ‘1‘: 1, ‘2‘: 2, ‘3‘: 3, ‘4‘: 4, ‘5‘: 5, ‘6‘: 6, ‘7‘: 7, ‘8‘: 8, ‘9‘: 9}[s] def str2int(s): return reduce(lambda x,y: x*10+y, map(char2num, s))
2015-05-02
python之函數式編程