亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

python中的裝飾器詳解

系統 1528 0

在了解裝飾器的之前一定要先了解函數作為參數傳遞, 什么是函數內嵌,請參考我之前寫的博客函數簡介

因為在python里面,函數也是對象,也可以作為參數進行傳遞.python裝飾器本質也是一種特殊函數,它接收的參數是函數對象,然后動態地函數參數添加額外的功能,而不用修改原有的函數對象. python裝飾器傳入的參數是函數,返回的值也是函數 !
python裝飾器思想有點類似設計模式的裝飾模式, 其意圖是動態地給函數對象添加額外的功能.比如像增加日志打印的功能,有點面向切面編程(AOP)的感覺.
裝飾器語法

以@開頭,接著后面跟著的是裝飾器的名字和可選的參數.裝飾器語法是一種語法糖.
格式如下

復制代碼 代碼如下:

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

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

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

簡單裝飾器

實例

復制代碼 代碼如下:

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

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

foo()
foo()


輸出
復制代碼 代碼如下:

start
In foo
end
In foo
In foo

帶內嵌函數裝飾器

內嵌函數保證每次新函數都被調用.而且被裝飾的函數可以帶有參數.
實例

復制代碼 代碼如下:

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

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

foo(123456)


輸出:
復制代碼 代碼如下:

start
In foo, get value is: 123456
end

帶參數的裝飾器

需要自己返回以函數作為參數的裝飾器。換句話說,decomaker()用 deco_args 做了些事并返回函數對象,而該函數對象正是以 foo 作為其參數的裝飾器。簡單的說來:foo=decomaker(deco_args)(foo)

實例

復制代碼 代碼如下:

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)


輸出
復制代碼 代碼如下:

In foo:? 123
get type is:? type2

總結

裝飾器本質是高階的函數,可以裝飾其他函數,增加被裝飾函數的功能,但不能覆蓋或改變被裝飾函數原有的行為.對于被裝飾的函數來說,裝飾器是透明的.裝飾器傳入參數為函數,返回的函數是被裝飾的函數.最后我們來實現給一個函數添加打印日志的功能,而不用改變這個函數.

復制代碼 代碼如下:

#!/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')


輸出:
復制代碼 代碼如下:

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


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 玖玖精品在线视频 | 国产h版大片在线播放 | 性感美女香蕉视频 | 精品综合久久久久久88小说 | 一区二区精品视频 | xoxo日本| 久久中国 | 国产精品久久国产三级国电话系列 | 老司机亚洲精品影院在线 | 91视频免费观看网站 | 一级片视频免费看 | 最新四虎4hu影库地址在线 | 国产亚洲精品一区二区在线播放 | 99精品福利视频 | 不卡在线播放 | 亚洲在线成人 | 中文字幕有码在线观看 | 欧美色综合| 一级毛片欧美一级日韩黄 | 黄片毛片在线看 | 91在线 | 欧美 | 亚洲欧美一区二区三区综合 | 亚欧人成精品免费观看 | 欧产日产国产精品专区 | 久久久国产精品福利免费 | 午夜激情男女 | 成人性视频免费网站 | 四虎影视www四虎免费 | 欧美国产综合在线 | 色综合久久六月婷婷中文字幕 | 福利岛国深夜在线 | 久青草国产手机在线观 | 青青热久久国产久精品 | 一级a毛片 | 日本美女视频韩国视频网站免费 | 在线成人爽a毛片免费软件 在线成人天天鲁夜啪视频 在线成人亚洲 | 中文字幕在线观看免费视频 | 天天舔天天操 | 中日韩欧美一级毛片 | 亚洲va高清中文字幕 | 国产精品98福利小视频 |