python中的匿名函數(shù)及編寫無(wú)參數(shù)decorator詳解
一、前言
高階函數(shù)可以接收函數(shù)做參數(shù),有些時(shí)候,我們不需要顯式地定義函數(shù),直接傳入匿名函數(shù)更方便。
在Python中,對(duì)匿名函數(shù)提供了有限支持。還是以map()函數(shù)為例,計(jì)算 f(x)=x2 時(shí),除了定義一個(gè) f(x)的函數(shù)外,還可以直接傳入匿名函數(shù):
>>> map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]) [1, 4, 9, 16, 25, 36, 49, 64, 81]
通過(guò)對(duì)比可以看出,匿名函數(shù) lambda x: x * x 實(shí)際上就是:
def f(x): return x * x
關(guān)鍵字lambda 表示匿名函數(shù),冒號(hào)前面的 x 表示函數(shù)參數(shù)。
匿名函數(shù)有個(gè)限制,就是只能有一個(gè)表達(dá)式,不寫return,返回值就是該表達(dá)式的結(jié)果。
使用匿名函數(shù),可以不必定義函數(shù)名,直接創(chuàng)建一個(gè)函數(shù)對(duì)象,很多時(shí)候可以簡(jiǎn)化代碼:
>>> sorted([1, 3, 9, 5, 0], lambda x,y: -cmp(x,y)) [9, 5, 3, 1, 0]
返回函數(shù)的時(shí)候,也可以返回匿名函數(shù):
>>> myabs = lambda x: -x if x < 0 else x >>> myabs(-1) 1 >>> myabs(1) 1
二、舉例
利用匿名函數(shù)簡(jiǎn)化以下代碼:
def is_not_empty(s): return s and len(s.strip()) > 0 filter(is_not_empty, ['test', None, '', 'str', ' ', 'END'])
定義匿名函數(shù)時(shí),沒(méi)有return關(guān)鍵字,且表達(dá)式的值就是函數(shù)返回值。參考代碼:
print filter(lambda s: s and len(s.strip())>0, ['test', None, '', 'str', ' ', 'END'])
三、python 編寫無(wú)參數(shù) decorator
Python的 decorator 本質(zhì)上就是一個(gè)高階函數(shù),它接收一個(gè)函數(shù)作為參數(shù),然后,返回一個(gè)新函數(shù)。
使用 decorator 用Python提供的 @ 語(yǔ)法,這樣可以避免手動(dòng)編寫 f = decorate(f) 這樣的代碼。
考察一個(gè)@log的定義:
def log(f): def fn(x): print 'call ' + f.__name__ + '()...' return f(x) return fn
對(duì)于階乘函數(shù),@log工作得很好:
@log def factorial(n): return reduce(lambda x,y: x*y, range(1, n+1)) print factorial(10)
結(jié)果:
call factorial()...3628800
但是,對(duì)于參數(shù)不是一個(gè)的函數(shù),調(diào)用將報(bào)錯(cuò):
@log def add(x, y): return x + y print add(1, 2)
結(jié)果:
Traceback (most recent call last): File "test.py", line 15, in <module> print add(1,2) TypeError: fn() takes exactly 1 argument (2 given)
因?yàn)?add() 函數(shù)需要傳入兩個(gè)參數(shù),但是 @log 寫死了只含一個(gè)參數(shù)的返回函數(shù)。
要讓 @log 自適應(yīng)任何參數(shù)定義的函數(shù),可以利用Python的 *args 和 **kw,保證任意個(gè)數(shù)的參數(shù)總是能正常調(diào)用:
def log(f): def fn(*args, **kw): print 'call ' + f.__name__ + '()...' return f(*args, **kw) return fn
現(xiàn)在,對(duì)于任意函數(shù),@log 都能正常工作。
四、舉例
請(qǐng)編寫一個(gè)@performance,它可以打印出函數(shù)調(diào)用的時(shí)間。
計(jì)算函數(shù)調(diào)用的時(shí)間可以記錄調(diào)用前后的當(dāng)前時(shí)間戳,然后計(jì)算兩個(gè)時(shí)間戳的差。參考代碼:
import time def performance(f): def fn(*args, **kw): t1 = time.time() r = f(*args, **kw) t2 = time.time() print 'call %s() in %fs' % (f.__name__, (t2 - t1)) return r return fn @performance def factorial(n): return reduce(lambda x,y: x*y, range(1, n+1)) print factorial(10)
到此這篇關(guān)于python中的匿名函數(shù)及編寫無(wú)參數(shù)decorator詳解的文章就介紹到這了,更多相關(guān)python匿名函數(shù)及無(wú)參數(shù)decorator內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python中執(zhí)行JavaScript實(shí)現(xiàn)數(shù)據(jù)抓取的多種方法
JavaScript是一門強(qiáng)大的腳本語(yǔ)言,廣泛應(yīng)用于網(wǎng)頁(yè)前端開(kāi)發(fā)、構(gòu)建交互式用戶界面以及處理各種客戶端端任務(wù),有時(shí)可能需要在Python環(huán)境中執(zhí)行JavaScript代碼,本文將介紹多種方法,幫助你在Python中執(zhí)行 JavaScript代碼,并提供詳盡的示例代碼,使你能夠輕松掌握這一技能2023-11-11Python利用matplotlib.pyplot.boxplot()繪制箱型圖實(shí)例代碼
相信大家應(yīng)該都知道Python繪制箱線圖主要用matplotlib庫(kù)里pyplot模塊里的boxplot()函數(shù),下面這篇文章主要給大家介紹了關(guān)于Python利用matplotlib.pyplot.boxplot()繪制箱型圖的相關(guān)資料,需要的朋友可以參考下2022-08-08Python?pandas?DataFrame數(shù)據(jù)拼接方法
我們都知道在使用pandas處理數(shù)據(jù)的時(shí)候,往往會(huì)需要合并兩個(gè)或者多個(gè)DataFrame的操作,下面這篇文章主要給大家介紹了關(guān)于Python?pandas?DataFrame數(shù)據(jù)拼接方法的相關(guān)資料,需要的朋友可以參考下2022-07-07python爬蟲(chóng)_微信公眾號(hào)推送信息爬取的實(shí)例
下面小編就為大家?guī)?lái)一篇python爬蟲(chóng)_微信公眾號(hào)推送信息爬取的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10如何在python中用os模塊實(shí)現(xiàn)批量移動(dòng)文件
在工作中難免會(huì)遇到需要批量整理文件的情況,當(dāng)需要從一堆文件中將部分文件批量地轉(zhuǎn)移時(shí),如果手工一一轉(zhuǎn)移難免浪費(fèi)時(shí)間,這篇文章主要給大家介紹了關(guān)于如何在python中用os模塊實(shí)現(xiàn)批量移動(dòng)文件的相關(guān)資料,需要的朋友可以參考下2022-05-05利用Python爬蟲(chóng)實(shí)現(xiàn)搶購(gòu)某寶秒殺商品
這篇文章主要介紹了利用Python爬蟲(chóng)實(shí)現(xiàn)搶購(gòu)某寶秒殺商品,文章基于python的相關(guān)資料展開(kāi)詳細(xì)的內(nèi)容介紹具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06Python中如何實(shí)現(xiàn)MOOC掃碼登錄
這篇文章主要介紹了Python中如何實(shí)現(xiàn)MOOC掃碼登錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01python+opencv實(shí)現(xiàn)車牌定位功能(實(shí)例代碼)
這篇文章主要介紹了python+opencv實(shí)現(xiàn)車牌定位功能,需要實(shí)現(xiàn)對(duì)給定的車牌進(jìn)行車牌識(shí)別,本文通過(guò)實(shí)例代碼講解,需要的朋友可以參考下2019-12-12