乙個需求的實現
當前,我們有這麼乙個小的需求:通過裝飾器來計算函式執行的時間
計算出這個函式的執行時長
def add(x,y): # add = timeit(add)
time.sleep(1)
'this is add'
return x + y
裝飾器實現
import time
import datetime
from functools import wraps
class timeit:
def __init__(self,fn):
print('init')
self._fn = fn
def __call__(self, *args, **kwargs):
start = datetime.datetime.now()
ret = self._fn(*args, **kwargs)
delta = datetime.datetime.now() - start
print(delta)
return ret
@timeit
def add(x,y): # add = timeit(add)
time.sleep(1)
'this is add'
return x + y
add(1,2)
print(add.__doc__)
print(add.__name__)
我們所看到的資訊如下:
traceback (most recent call last):
file "h:/python_project/test2/3.py", line 33, in print(add.__name__)
attributeerror: 'timeit' object has no attribute '__name__'
那麼問題來了,在列印__doc__ 和 __name__ 的時候看到返回的並非是我們想要的,因為已經被包裝到timeit中的可呼叫物件,所以,現在它是乙個例項了,例項是不能呼叫__name__的;所以,我們來手動模擬一下,將其偽裝寫入__doc__ 和 __name__
改造
手動拷貝:粗糙的改造方式,將其__doc__ __name__強行複製到例項中
self無非是我們當前所繫結的類例項,fn是通過裝飾器傳遞進來的add,我們將fn的doc 和 name 作為源強行的賦值到self中,如下:
class timeit:
def __init__(self,fn):
print('init')
self._fn = fn
# 函式的doc 拷貝到 fn中
self.__doc__ = self._fn.__doc__
self.__name__ = self._fn.__name__
這樣效果肯定是不好的,這樣做就是為了得知其儲存位置,那麼接下來引入wraps模組
引入wraps
wraps本質是乙個函式裝飾器,通過接收乙個引數再接收乙個引數進行傳遞並處理,反正網上也一堆使用方法,舉例不再說明,但是這裡需要將函式呼叫的等價式摸清
使用方式:
from functools import wraps
def looger(fn):
@wraps(fn)
******xx
過程分析
首先我們通過編輯器跟進到函式內部
"""
可看到wraps中,需要傳遞幾個引數,跟進到assigned,被包裝的函式才是src源,也就是說被外部的更新掉
'__annotations__')
iOS螢幕適配那點兒事
首先要明白幾個概念 座標 表示螢幕的物理尺寸大小 畫素 表示螢幕的大小,和座標之間的比值對我們很重要,一般是1 1或1 2.ppi 就是座標和畫素的比值。ios螢幕適配可以分為兩部分,一 螢幕大小的適配,二 畫素的適配。螢幕大小的適配 5 5s 5c之後,因為螢幕的大小改變了,使用絕對定位是不可行的...
雲儲存市場的那點兒事
中云網 原創 據市場研究公司idc最近發表的研究報告顯示,公共雲服務提供商從2010年至2015年在儲存硬體 軟體和專業服務方面的開支將以平均每年23.6 的速度增長。idc儲存系統和執行戰略部副總裁richard villars表示,到2015年,全球公共雲和私有雲儲存開支將達到226億美元。雲儲...
《BI那點兒事》Cube的儲存
原文 bi那點兒事 cube的儲存 關係 olap rolap rolap的基本資料和聚合資料均存放在關聯式資料庫中 rolap 儲存模式使得分割槽的聚合儲存在關聯式資料庫的表 在分割槽資料來源中指定 中。但是,可為分割槽資料使用 rolap 儲存模式,而不在關聯式資料庫中建立聚合。使用 rolap...