Python入門篇-functoolspython
做者:尹正傑程序員
版權聲明:原創做品,謝絕轉載!不然將追究法律責任。緩存
一.partial方法分佈式
1>.partial概述ide
偏函數,把函數部分的參數固定下來,至關於爲部分的參數添加了一個固定的默認值,造成一個新的函數並返回
從partial生成的新函數,是對原函數的封裝
2>.partial方法舉例函數
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 8 import functools,inspect 9 10 def add(x, y, *args) -> int: 11 print("add args:{}".format(args)) 12 return x + y 13 14 newadd = functools.partial(add, y=5) 15 16 print(inspect.signature(add)) 17 print(newadd(7)) 18 print(newadd(10, y=20)) 19 print(newadd(y=10, x=6)) 20 print(inspect.signature(newadd)) 21 22 23 24 #以上代碼執行結果以下: 25 (x, y, *args) -> int 26 add args:() 27 12 28 add args:() 29 30 30 add args:() 31 16 32 (x, *, y=5) -> int
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 8 import functools,inspect 9 10 def add(x, y, *args) -> int: 11 print("add args:{}".format(args)) 12 return x + y 13 14 newadd = functools.partial(add, 1,3,6,5) 15 print(newadd(7)) 16 print(newadd(7, 10)) 17 print(newadd()) 18 print(inspect.signature(add)) 19 print(inspect.signature(newadd)) 20 21 22 23 #以上代碼執行結果以下: 24 add args:(6, 5, 7) 25 4 26 add args:(6, 5, 7, 10) 27 4 28 add args:(6, 5) 29 4 30 (x, y, *args) -> int 31 (*args) -> int
3>.partial函數本質spa
def partial(func, *args, **keywords): def newfunc(*fargs, **fkeywords): # 包裝函數 newkeywords = keywords.copy() newkeywords.update(fkeywords) return func(*(args + fargs), **newkeywords) newfunc.func = func # 保留原函數 newfunc.args = args # 保留原函數的位置參數 newfunc.keywords = keywords # 保留原函數的關鍵字參數參數 return newfunc
def add(x,y): return x+y
foo = partial(add,4) foo(5)
二.lru_cache方法設計
1>.lru_cache概述code
@functools.lru_cache(maxsize=128, typed=False) Least-recently-used裝飾器。lru,最近最少使用。cache緩存 若是maxsize設置爲None,則禁用LRU功能,而且緩存能夠無限制增加。當maxsize是二的冪時,LRU功能執行得最好 若是typed設置爲True,則不一樣類型的函數參數將單獨緩存。例如,f(3)和f(3.0)將被視爲具備不一樣結果的不一樣調用
2>. lru_cache舉例orm
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 8 import functools 9 import time 10 11 @functools.lru_cache() 12 def add(x, y, z=3): 13 time.sleep(z) 14 return x + y 15 16 print(add(4, 5)) 17 print(add(4.0, 5)) 18 print(add(4, 6)) 19 print(add(4, 6, 3)) 20 print(add(3, 2)) 21 print(add(2, y=3)) 22 print(add(x=40, y=60)) 23 print(add(y=60, x=40))
3>.lru_cache裝飾器
經過一個字典緩存被裝飾函數的調用和返回值 key是什麼?分析代碼看看 functools._make_key((4,6),{'z':3},False) functools._make_key((4,6,3),{},False) functools._make_key(tuple(),{'z':3,'x':4,'y':6},False) functools._make_key(tuple(),{'z':3,'x':4,'y':6}, True)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 8 import functools 9 10 @functools.lru_cache() # maxsize=None 11 def fib(n): 12 if n < 3: 13 return n 14 return fib(n-1) + fib(n-2) 15 16 print([fib(x) for x in range(35)]) 17 18 19 20 21 #以上代碼執行結果以下: 22 [0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465]
4>.lru_cache裝飾器應用
使用前提 一樣的函數參數必定獲得一樣的結果 函數執行時間很長,且要屢次執行
本質是函數調用的參數=>返回值
缺點 不支持緩存過時,key沒法過時、失效 不支持清除操做 不支持分佈式,是一個單機的緩存
適用場景,單機上須要空間換時間的地方,能夠用緩存來將計算變成快速的查詢
三.裝飾器應用練習
1>.實現一個cache裝飾器,實現可過時被清除的功能
簡化設計,函數的形參定義不包含可變位置參數、可變關鍵詞參數和keyword-only參數
能夠不考慮緩存滿了以後的換出問題
2>.寫一個命令分發器
程序員能夠方便的註冊函數到某一個命令,用戶輸入命令時,路由到註冊的函數
若是此命令沒有對應的註冊函數,執行默認函數
用戶輸入用input(">>")