匿名函數(shù)
1)匿名函數(shù)有個限制幌甘,就是只能有一個表達式潮售,不用寫return,返回值就是該表達式的結(jié)果锅风。
2)因為沒有名字酥诽,不必擔心函數(shù)名沖突
3)可以把匿名函數(shù)賦值給一個變量,再利用變量來調(diào)用該函數(shù)
4)同樣皱埠,也可以把匿名函數(shù)作為返回值返回肮帐,比如:
def build(x, y):
? ? return lambda: x * x + y * y
裝飾器
1)函數(shù)對象有一個__name__屬性,可以拿到函數(shù)的名字
2)這種在代碼運行期間動態(tài)增加功能的方式边器,稱之為“裝飾器”(Decorator)训枢,decorator就是一個返回函數(shù)的高階函數(shù)
def log(func):
? ? def wrapper(*args, **kw):
? ? ? ? print('call %s():' % func.__name__)
? ? ? ? return func(*args, **kw)
? ? return wrapper
觀察上面的log,因為它是一個decorator忘巧,所以接受一個函數(shù)作為參數(shù)恒界,并返回一個函數(shù)。我們要借助Python的@語法砚嘴,把decorator置于函數(shù)的定義處:
@log
def now():
? ? ?print('2015-3-25')
調(diào)用now()函數(shù)仗处,不僅會運行now()函數(shù)本身眯勾,還會在運行now()函數(shù)前打印一行日志:
>>> now()
call now():
2015-3-25
把@log放到now()函數(shù)的定義處枣宫,相當于執(zhí)行了語句:
now= log(now)如果decorator本身需要傳入?yún)?shù)婆誓,那就需要編寫一個返回decorator的高階函數(shù),寫出來會更復雜也颤。比如洋幻,要自定義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
這個3層嵌套的decorator用法如下:
@log('execute')
def now():
? ? print('2015-3-25')
執(zhí)行結(jié)果如下:
>>> now()
execute now():
2015-3-25
和兩層嵌套的decorator相比,3層嵌套的效果是這樣的:
>>> now = log('execute')(now)
首先執(zhí)行l(wèi)og('execute')翅娶,返回的是decorator函數(shù)文留,再調(diào)用返回的函數(shù),參數(shù)是now函數(shù)竭沫,返回值最終是wrapper函數(shù)燥翅。
3)因為返回的那個wrapper()函數(shù)名字就是'wrapper',所以蜕提,需要把原始函數(shù)的__name__等屬性復制到wrapper()函數(shù)中森书,否則,有些依賴函數(shù)簽名的代碼執(zhí)行就會出錯谎势。
即在總的編寫前加上:
import functools
在wrapper定義前加上:
@functools.wraps(func)
使用時在案例代碼上進行修改可以簡單得到想要的效果
自己打一遍理解起來更快