python3装饰器的高级使用
生活随笔
收集整理的這篇文章主要介紹了
python3装饰器的高级使用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
#practice26:緩存與裝飾器(遞歸子問題)
對于需要重復計算子問題的情況,可以使用緩存,緩存實現有兩種方式:1.在函數內定義某種數據結構存儲數據 2.使用裝飾器(閉包結構)
菲波那切數列為:1,1,2,3,5,8,13;即從第三項開始,每一項為前兩項之和。
以菲波那切數列為例
1、一般的實現方式為:
#求第n項的斐波那契數,從0開始 def fibonacci(n):if n <= 1:return 1return fibonacci(n-1) + fibonacci(n-2)print(fibonacci(33))上述函數中由于需要重復計算某些項,所以計算速度非常緩慢,如果在計算過程中能保存一些中間值,速度提升非常明顯
2、使用緩存:保存中間值
#方法一:緩存法 #cache以值None層層傳遞到最底層,然后創建空字典 #cache逐層傳遞引用,每層的變量cache均指向同一對象! def fibonacci(n,cache=None):if cache is None:cache = {}if n in cache.keys():return cache[n]if n <= 1:return 1cache[n] = fibonacci(n-1,cache) + fibonacci(n-2,cache)return cache[n]print(fibonacci(33))這種儲存中間值的方法不太直觀
3、 使用裝飾器,利用閉包保存中間值
#方法二:使用裝飾器,一來不改變函數形式,二可利用閉包保存變量狀態,比緩存法容易理解 def decorator(f):cache = {}def wrapper(*args,**kargs):if args not in cache.keys():cache[args] = f(*args,**kargs)return cache[args]return wrapper@decorator def fibonacci(n):if n <= 1:return 1return fibonacci(n-1) + fibonacci(n-2) print(fibonacci(33))裝飾器中閉包的典型使用場景
#practice27:函數元數據與裝飾器
1、 函數元數據
def f(key,a=1,b=[]):'''function f'''print(b)print(key*2) #函數名稱 print(f.__name__) #函數注釋 print(f.__doc__) #函數所屬模塊 print(f.__module__) #函數的默認參數元組 print(f.__defaults__) #修改函數參數的默認參數居然成功了,因為元組內包含列表,列表是可變對象! #正因如此,不應該把可變對象作為參數的默認值! f.__defaults__[1].append('100') f(1) ##會報錯,元組的元素不可被賦值 #f.__defaults__[0] = 10 #f(1)def func1():a = 3return lambda x: a*x g = func1() #讀取函數的閉包 #每個閉包包含多個cell對象 print(g.__closure__) #cell對象的cell_contents屬性可以讀取值 print(g.__closure__[0].cell_contents)2、 使用裝飾器后函數如何保留元數據?
- 被裝飾后的函數,其元數據改為了wrapper函數!
- 手動修改元數據
- 使用functools模塊中的update_wrapper函數與常量
- 使用functools中的wraps裝飾器(帶參數)
此為推薦方法
#practice28:帶參數裝飾器
1、示例:實現函數參數類型檢查
def type(*types,**ktypes):def decorator(func):def wrapper(*args,**kargs):allmatch = Truefor value,_type in zip(args,types):if not isinstance(value,_type):print("value: " + str(value) + " is not " + str(_type))allmatch = Falsebreakif allmatch:func(*args,**kargs)return wrapperreturn decorator@type(int,str,int) def f1(a,b,c):print(a,b,c)@type(int,int,str,tuple) def f2(a,b,c,d):print(a,b,c,d)f1("s",'qq',55) f2(1,2,3,4) f2(1,2,"qq",(22,33))裝飾器的參數最終還是要使用在wrapper內!
2、示例:屬性可修改的函數裝飾器
- 實現函數運行時間檢查
- 使裝飾器屬性可修改
溫習一下函數作為一等對象如何定義屬性!
總結
以上是生活随笔為你收集整理的python3装饰器的高级使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 每天5分钟玩转python3算法:二分查
- 下一篇: ubuntu18.04安装pycharm