日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

python中的裝飾器詳解

系統(tǒng) 1766 0

在了解裝飾器的之前一定要先了解函數(shù)作為參數(shù)傳遞, 什么是函數(shù)內(nèi)嵌,請(qǐng)參考我之前寫(xiě)的博客函數(shù)簡(jiǎn)介

因?yàn)樵趐ython里面,函數(shù)也是對(duì)象,也可以作為參數(shù)進(jìn)行傳遞.python裝飾器本質(zhì)也是一種特殊函數(shù),它接收的參數(shù)是函數(shù)對(duì)象,然后動(dòng)態(tài)地函數(shù)參數(shù)添加額外的功能,而不用修改原有的函數(shù)對(duì)象. python裝飾器傳入的參數(shù)是函數(shù),返回的值也是函數(shù) !
python裝飾器思想有點(diǎn)類(lèi)似設(shè)計(jì)模式的裝飾模式, 其意圖是動(dòng)態(tài)地給函數(shù)對(duì)象添加額外的功能.比如像增加日志打印的功能,有點(diǎn)面向切面編程(AOP)的感覺(jué).
裝飾器語(yǔ)法

以@開(kāi)頭,接著后面跟著的是裝飾器的名字和可選的參數(shù).裝飾器語(yǔ)法是一種語(yǔ)法糖.
格式如下

復(fù)制代碼 代碼如下:

@decomaker(deco_args)
??? def foo(func_opt_args)

可以組合,等價(jià)于foo = g(f(foo))
復(fù)制代碼 代碼如下:

@g
@f
def foo():
??? statement

簡(jiǎn)單裝飾器

實(shí)例

復(fù)制代碼 代碼如下:

#!/usr/bin/python
def? deco(func):
??? print 'start'
??? func()
??? print 'end'
??? return func

@deco
def foo():
??? print 'In foo'

foo()
foo()


輸出
復(fù)制代碼 代碼如下:

start
In foo
end
In foo
In foo

帶內(nèi)嵌函數(shù)裝飾器

內(nèi)嵌函數(shù)保證每次新函數(shù)都被調(diào)用.而且被裝飾的函數(shù)可以帶有參數(shù).
實(shí)例

復(fù)制代碼 代碼如下:

def? deco(func):
??? def _deco(x):??? #該函數(shù)為內(nèi)嵌函數(shù)
??????? print 'start'
??????? func(x)
??????? print 'end'
??? return _deco

@deco
def foo(x):
??? print 'In foo, get value is: %d' % x

foo(123456)


輸出:
復(fù)制代碼 代碼如下:

start
In foo, get value is: 123456
end

帶參數(shù)的裝飾器

需要自己返回以函數(shù)作為參數(shù)的裝飾器。換句話說(shuō),decomaker()用 deco_args 做了些事并返回函數(shù)對(duì)象,而該函數(shù)對(duì)象正是以 foo 作為其參數(shù)的裝飾器。簡(jiǎn)單的說(shuō)來(lái):foo=decomaker(deco_args)(foo)

實(shí)例

復(fù)制代碼 代碼如下:

def deco(arg):
??? def wrapper1(func):
??????? def _deco(x):
??????????? print "get type is: ", arg
??????????? func(x)
??????? return _deco

??? def wrapper2(func):
??????? def _deco(x):
??????????? func(x)
??????????? print "get type is: ", arg
??????? return _deco

??? if arg == 'type1':
??????? return wrapper1
??? else:
??????? return wrapper2

@deco("type2")
def foo(x):
??? print 'In foo: ', x

foo(123)


輸出
復(fù)制代碼 代碼如下:

In foo:? 123
get type is:? type2

總結(jié)

裝飾器本質(zhì)是高階的函數(shù),可以裝飾其他函數(shù),增加被裝飾函數(shù)的功能,但不能覆蓋或改變被裝飾函數(shù)原有的行為.對(duì)于被裝飾的函數(shù)來(lái)說(shuō),裝飾器是透明的.裝飾器傳入?yún)?shù)為函數(shù),返回的函數(shù)是被裝飾的函數(shù).最后我們來(lái)實(shí)現(xiàn)給一個(gè)函數(shù)添加打印日志的功能,而不用改變這個(gè)函數(shù).

復(fù)制代碼 代碼如下:

#!/usr/bin/python
#coding=utf-8
import functools

def log(prefix, suffix):
??? def deco(func):
??????? @functools.wraps(func)
??????? def wrapper(*args, **kargs):
??????????? print '%s log start' % prefix
??????????? print('get a is: %s' % args[0])
??????????? print('get b is: %s' % args[1])
??????????? print('get c is: %s' % args[2])
??????????? print('get d is: %s' % kargs['d'])
??????????? print('get d is: %s' % kargs['f'])
??????????? func(*args, **kargs)
??????????? print '%s log end' % suffix
??????? return wrapper
??? return deco

@log('logstart', 'logend')
def test(a, b, c, d, f):
??? print 'call func name is: %s' % test.__name__

test(1, 2, 3, d = 'dddd', f = 'ffff')


輸出:
復(fù)制代碼 代碼如下:

logstart log start
get a is: 1
get b is: 2
get c is: 3
get d is: dddd
get d is: ffff
call func name is: test
logend log end


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 定州市| 连山| 紫阳县| 桂平市| 且末县| 延吉市| 万盛区| 靖西县| 苗栗市| 秦安县| 聂拉木县| 马山县| 西吉县| 从江县| 阳谷县| 青河县| 南乐县| 合作市| 林甸县| 启东市| 碌曲县| 岗巴县| 东乌珠穆沁旗| 濮阳市| 宁化县| 开封市| 黑河市| 仁化县| 长宁县| 丹江口市| 汝州市| 正镶白旗| 泰来县| 崇礼县| 永宁县| 贵州省| 苍山县| 长治县| 沈丘县| 仁寿县| 东乌珠穆沁旗|