Python實(shí)現(xiàn)屬性可修改的裝飾器方式
如何實(shí)現(xiàn)屬性可修改的函數(shù)裝飾器
實(shí)際案例
為分析程序內(nèi)哪些函數(shù)執(zhí)行時(shí)間開(kāi)銷(xiāo)比較大,
我們定義一個(gè)帶timeout參數(shù)的函數(shù)裝飾器,timeout是一個(gè)時(shí)間閥值
比如運(yùn)行時(shí)間超過(guò)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ù)的屬性,用來(lái)修改閉包中使用的自由變量。
在python3中:使用nonlocal訪問(wèn)嵌套作用域中的變量引用。
代碼演示
# _*_ 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)闆](méi)有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聲明嵌套作用域下變量,類(lèi)似于global
nonlocal timeout
timeout = k
# python2中使用可變對(duì)象修改timeout
# timeout[0] = k
# 將set_timeout函數(shù)作為wrapper屬性,未來(lái)用戶(hù)就可以通過(guò)函數(shù)來(lái)調(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庫(kù)的查詢(xún)操作的教程
這篇文章主要介紹了Python的ORM框架中SQLAlchemy庫(kù)的查詢(xún)操作的教程,SQLAlchemy用來(lái)操作數(shù)據(jù)庫(kù)十分方便,需要的朋友可以參考下2015-04-04
tensorflow實(shí)現(xiàn)從.ckpt文件中讀取任意變量
這篇文章主要介紹了tensorflow實(shí)現(xiàn)從.ckpt文件中讀取任意變量,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-05-05
Python實(shí)現(xiàn)自定義異常實(shí)例
大家好,本篇文章主要講的是Python實(shí)現(xiàn)自定義異常實(shí)例,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01

