這種在**執行期間動態增加功能的方式,稱之為「裝飾器」(decorator)。
>>> def now():
... print('2015-3-25')
...>>> f = now
>>> f()
2015-3-25
函式物件有乙個__name__
屬性,可以拿到函式的名字:
>>> now.__name__
'now'
>>> f.__name__
'now'
本質上,decorator就是乙個返回函式的高階函式。所以,我們要定義乙個能列印日誌的decorator,可以定義如下:
def log(func):
print('call %s():' % func.__name__)
return func(*args, **kw)
本質上,decorator就是乙個返回函式的高階函式。所以,我們要定義乙個能列印日誌的decorator,可以定義如下:
def log(func):觀察上面的print('call %s():' % func.__name__)
return func(*args, **kw)
log
,因為它是乙個decorator,所以接受乙個函式作為引數,並返回乙個函式。我們要借助python的@語法,把decorator置於函式的定義處:
@log
def now():
print('2015-3-25')
呼叫now()
函式,不僅會執行now()
函式本身,還會在執行now()
函式前列印一行日誌:
>>> now()
call now():
2015-3-25
把@log
放到now()
函式的定義處,相當於執行了語句:
now = log(now)
如果decorator本身需要傳入引數,那就需要編寫乙個返回decorator的高階函式,寫出來會更複雜。比如,要自定義log的文字:
def log(text):
def decorator(func):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return decorator
這個3層巢狀的decorator用法如下:
@log('execute')
def now():
print('2015-3-25')
執行結果如下:
>>> now()
execute now():
2015-3-25
和兩層巢狀的decorator相比,3層巢狀的效果是這樣的:
>>> now = log('execute')(now)
>>> now.__name__
import functools
def log(func):
@functools.wraps(func)
print('call %s():' % func.__name__)
return func(*args, **kw)
或者針對帶引數的decorator:
import functools
def log(text):
def decorator(func):
@functools.wraps(func)
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return decorator
在物件導向(oop)的設計模式中,decorator被稱為裝飾模式。oop的裝飾模式需要通過繼承和組合來實現,而python除了能支援oop的decorator外,直接從語法層次支援decorator。python的decorator可以用函式實現,也可以用類實現。
decorator可以增強函式的功能,定義起來雖然有點複雜,但使用起來非常靈活和方便。
請編寫乙個decorator,能在函式呼叫的前後列印出'begin call'
和'end call'
的日誌。
再思考一下能否寫出乙個@log
的decorator,使它既支援:
@log
def f():
pass
又支援:
@log('execute')
def f():
pass
import timedef metric(fn):
print('%s executed in %s ms' % (fn.__name__, fn(*args, **kw)))
return fn(*args, **kw)
python廖雪峰教程 學習筆記
如何用字元來描述字元 d匹配數字 digit w匹配字母或數字 word s可以匹配空格 space 表示任意個字元,表示至少乙個字元 表示0個或1個字元,表示n個字元,表示n m個字元 可以匹配任意字元 例如 kongxiangyu w如何做到更精確的匹配?規定數字 字母或者下劃線 0 9a za...
Git 廖雪峰 學習筆記
目錄 git工作區域 git初始化及倉庫建立和操作 初始化新的git倉庫 1.新建資料夾 2.在檔案內初始化git 如何將本地倉庫同步到git 遠端倉庫 1.關聯遠端庫 2.第一次推送master分支的所有內容 3.每次本地提交後,推送最新修改 轉殖 分支管理 1.建立與合併分支 2.解決衝突 3....
git 廖雪峰學習筆記
git的誕生 linus堅決反對cvs和svn等集中式版本控制系統 因為速度慢且需要聯網 bitmover公司授權linux社群商業軟體bitkeeper免費使用權 linus社群牛人試圖破解bitkeeper的協議被bitmover公司發現 bitmover公司收回linux社群bitkeeper...