国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python中裝飾器學(xué)習(xí)總結(jié)

2020-01-04 15:53:16
字體:
供稿:網(wǎng)友

本文研究的主要內(nèi)容是Python中裝飾器相關(guān)學(xué)習(xí)總結(jié),具體如下。

裝飾器(decorator)功能

  • 引入日志
  • 函數(shù)執(zhí)行時間統(tǒng)計
  • 執(zhí)行函數(shù)前預(yù)備處理
  • 執(zhí)行函數(shù)后清理功能
  • 權(quán)限校驗等場景
  • 緩存

裝飾器示例

例1:無參數(shù)的函數(shù)

from time import ctime, sleepdef timefun(func): def wrappedfunc():  print("%s called at %s"%(func.__name__, ctime()))  func() return wrappedfunc@timefundef foo(): print("I am foo")foo()sleep(2)foo()

分析如下:

上面代碼理解裝飾器執(zhí)行行為可理解成

foo = timefun(foo)

1,foo先作為參數(shù)賦值給func后,foo接收指向timefun返回的wrappedfunc
2,調(diào)用foo(),即等價調(diào)用wrappedfunc()
3,內(nèi)部函數(shù)wrappedfunc被引用,所以外部函數(shù)的func變量(自由變量)并沒有釋放
4,func里保存的是原foo函數(shù)對象

例2:被裝飾的函數(shù)有參數(shù)

from time import ctime, sleepdef timefun(func): def wrappedfunc(a, b):  print("%s called at %s"%(func.__name__, ctime()))  print(a, b)  func(a, b) return wrappedfunc@timefundef foo(a, b): print(a+b)foo(3,5)sleep(2)foo(2,4)

例3:被裝飾的函數(shù)有不定長參數(shù)

from time import ctime, sleepdef timefun(func): def wrappedfunc(*args, **kwargs):  print("%s called at %s"%(func.__name__, ctime()))  func(*args, **kwargs) return wrappedfunc@timefundef foo(a, b, c): print(a+b+c)foo(3,5,7)sleep(2)foo(2,4,9)

例4:裝飾器中的return

from time import ctime, sleepdef timefun(func): def wrappedfunc():  print("%s called at %s"%(func.__name__, ctime()))  func() return wrappedfunc@timefundef foo(): print("I am foo")@timefundef getInfo(): return '----hahah---'foo()sleep(2)foo()print(getInfo())

執(zhí)行結(jié)果:

foo called at Sun Jun 18 00:31:53 2017
I am foo
foo called at Sun Jun 18 00:31:55 2017
I am foo
getInfo called at Sun Jun 18 00:31:55 2017
None

如果修改裝飾器為return func(),則運行結(jié)果:

foo called at Sun Jun 18 00:34:12 2017
I am foo
foo called at Sun Jun 18 00:34:14 2017
I am foo
getInfo called at Sun Jun 18 00:34:14 2017
----hahah---

小結(jié):一般情況下為了讓裝飾器更通用,可以有return

例5:裝飾器帶參數(shù),在原有裝飾器的基礎(chǔ)上,設(shè)置外部變量

from time import ctime, sleepdef timefun_arg(pre="hello"): def timefun(func):  def wrappedfunc():   print("%s called at %s %s"%(func.__name__, ctime(), pre))   return func()  return wrappedfunc return timefun@timefun_arg("itcast")def foo(): print("I am foo")@timefun_arg("python")def too(): print("I am too")foo()sleep(2)foo()too()sleep(2)too()可以理解為foo()==timefun_arg("itcast")(foo)()

例6:類裝飾器

裝飾器函數(shù)其實是這樣一個接口約束,它必須接受一個callable對象作為參數(shù),然后返回一個callable對象。在Python中一般callable對象都是函數(shù),但也有例外。只要某個對象重寫了 call() 方法,那么這個對象就是callable的。

class Test(): def __call__(self):  print('call me!')t = Test()t() # call me類裝飾器democlass Test(object): def __init__(self, func):  print("---初始化---")  print("func name is %s"%func.__name__)  self.__func = func def __call__(self):  print("---裝飾器中的功能---")  self.__func()

說明:

1. 當(dāng)用Test來裝作裝飾器對test函數(shù)進(jìn)行裝飾的時候,首先會創(chuàng)建Test的實例對象,并且會把test這個函數(shù)名當(dāng)做參數(shù)傳遞到init方法中
即在init方法中的func變量指向了test函數(shù)體
2. test函數(shù)相當(dāng)于指向了用Test創(chuàng)建出來的實例對象
3. 當(dāng)在使用test()進(jìn)行調(diào)用時,就相當(dāng)于讓這個對象(),因此會調(diào)用這個對象的call方法
4. 為了能夠在call方法中調(diào)用原來test指向的函數(shù)體,所以在init方法中就需要一個實例屬性來保存這個函數(shù)體的引用
所以才有了self.func = func這句代碼,從而在調(diào)用__call方法中能夠調(diào)用到test之前的函數(shù)體

@Test def test(): print(“—-test—”) test() showpy()#如果把這句話注釋,重新運行程序,依然會看到”–初始化–”

運行結(jié)果如下:

---初始化---
func name is test
---裝飾器中的功能---
----test---

wraps函數(shù)

使用裝飾器時,有一些細(xì)節(jié)需要被注意。例如,被裝飾后的函數(shù)其實已經(jīng)是另外一個函數(shù)了(函數(shù)名等函數(shù)屬性會發(fā)生改變)。

添加后由于函數(shù)名和函數(shù)的doc發(fā)生了改變,對測試結(jié)果有一些影響,例如:

def note(func): "note function" def wrapper():  "wrapper function"  print('note something')  return func() return wrapper@notedef test(): "test function" print('I am test')test()print(test.__doc__)

運行結(jié)果

note something
I am test
wrapper function

所以,Python的functools包中提供了一個叫wraps的裝飾器來消除這樣的副作用。例如:

import functoolsdef note(func): "note function" @functools.wraps(func) def wrapper():  "wrapper function"  print('note something')  return func() return wrapper@notedef test(): "test function" print('I am test')test()print(test.__doc__)

運行結(jié)果

note something
I am test
test function

總結(jié)

以上就是本文關(guān)于Python中裝飾器學(xué)習(xí)總結(jié)的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!


注:相關(guān)教程知識閱讀請移步到python教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 上饶县| 宿松县| 石泉县| 达拉特旗| 正宁县| 乳源| 黄梅县| 临汾市| 渝中区| 泉州市| 合阳县| 太原市| 凤山县| 贺兰县| 澳门| 合江县| 广昌县| 石狮市| 上饶县| 峨山| 武穴市| 图木舒克市| 日土县| 湖北省| 巴彦县| 剑阁县| 西青区| 晋宁县| 凤阳县| 永新县| 连平县| 武汉市| 龙州县| 峨眉山市| 沭阳县| 淮安市| 旬阳县| 乌拉特中旗| 宜宾县| 东方市| 河北区|