python學習筆記 廖雪峰(26 裝飾器)

2021-09-12 23:16:44 字數 2708 閱讀 1833

這種在**執行期間動態增加功能的方式,稱之為「裝飾器」(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 time

def 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...