Python實(shí)現(xiàn)屬性可修改的裝飾器方式
如何實(shí)現(xiàn)屬性可修改的函數(shù)裝飾器
實(shí)際案例
為分析程序內(nèi)哪些函數(shù)執(zhí)行時(shí)間開銷比較大,
我們定義一個(gè)帶timeout參數(shù)的函數(shù)裝飾器,timeout是一個(gè)時(shí)間閥值
比如運(yùn)行時(shí)間超過1秒的都是比較慢的,這種函數(shù)比較可疑。
裝飾器功能如下:
- 統(tǒng)計(jì)被裝飾函數(shù)單詞調(diào)用運(yùn)行時(shí)間;
- 時(shí)間大于參數(shù)timeout的,將此次函數(shù)調(diào)用記錄到log日志中;
- 運(yùn)行時(shí)可修改timeout的值(可以動(dòng)態(tài)修改timeout)。
解決方案
為包裹函數(shù)增加一個(gè)函數(shù)作為包裹函數(shù)的屬性,用來修改閉包中使用的自由變量。
在python3中:使用nonlocal訪問嵌套作用域中的變量引用。
代碼演示
# _*_ encoding:utf-8 _*_ from functools import wraps from random import randint import time import logging # 內(nèi)部統(tǒng)計(jì)一個(gè)算法的運(yùn)行時(shí)間 def warn(timeout): """ 帶參數(shù)裝飾器也就是內(nèi)部能返回一個(gè)裝飾器 """ # python2中因?yàn)闆]有nonlocal,可以將timeout聲明為可變對(duì)象 # timeout = [timeout] # 裝飾器冬季func運(yùn)行時(shí)間 def decorator(func): # 定義包裹函數(shù) def wrapper(*args, **kwargs): start = time.time() res = func(*args, **kwargs) # 得到運(yùn)行時(shí)間 used = time.time() - start if used > timeout: msg = '"%s": %s > %s' % (func.__name__, used, timeout) # 如果超時(shí)輸入到日志當(dāng)中 logging.warning(msg) # if used > timeout[0]: # msg = '"%s": %s > %s' % (func.__name__, used, timeout[0]) # logging.warn(msg) # return res # 動(dòng)態(tài)修改函數(shù)屬性timeout值 def set_timeout(k): # python3聲明嵌套作用域下變量,類似于global nonlocal timeout timeout = k # python2中使用可變對(duì)象修改timeout # timeout[0] = k # 將set_timeout函數(shù)作為wrapper屬性,未來用戶就可以通過函數(shù)來調(diào)用到它。 wrapper.set_timeout = set_timeout return wrapper return decorator # 測(cè)試代碼 @warn(1.5) def test(): print('In test') # 隨機(jī)進(jìn)入睡眠狀態(tài),百分之50概率 while randint(0, 1): time.sleep(0.5) for _ in range(30): test() # 測(cè)試運(yùn)行時(shí)修改timeout屬性等于1 test.set_timeout(1) for _ in range(30): test() ''' 運(yùn)行完前30個(gè)test函數(shù)后修改timeout=1。 運(yùn)行時(shí)可以看到timeout從1.5變成了1,如下: WARNING:root:"test": 1.509084939956665 > 1.5 WARNING:root:"test": 1.004662036895752 > 1 '''
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python的ORM框架中SQLAlchemy庫的查詢操作的教程
這篇文章主要介紹了Python的ORM框架中SQLAlchemy庫的查詢操作的教程,SQLAlchemy用來操作數(shù)據(jù)庫十分方便,需要的朋友可以參考下2015-04-04tensorflow實(shí)現(xiàn)從.ckpt文件中讀取任意變量
這篇文章主要介紹了tensorflow實(shí)現(xiàn)從.ckpt文件中讀取任意變量,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-05-05Python實(shí)現(xiàn)自定義異常實(shí)例
大家好,本篇文章主要講的是Python實(shí)現(xiàn)自定義異常實(shí)例,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01