functools 包含了用於建立裝飾函數,啓動面向切面的編程,超出面向對象編程範圍的代碼複用,同時提供了裝飾函數用於豐富的快捷比較的API, partial 模塊還建立了包含函數參數的函數引用,也就是偏函數python
partial 的做用在於若是存在一個函數的參數過多,能夠經過partial 固定某一些參數,須要的時候使用關鍵字參數傳入便可.經過一個簡單的例子理解編程
import functools def myfunc(a,b): print("This is myfuc params:{},{}".format(a,b)) a = functools.partial(myfunc,b=1) a(10000)
能夠看到,原本調用myfunc的話,要傳入兩個參數,如今經過固定住某些參數,能夠直接調用一個參數便可。除此以外,還能夠經過另一種方式來進行傳值less
import functools def myfunc(a,b): print("This is myfuc params:{},{}".format(a,b)) a = functools.partial(myfunc,b=1) value= {"a":1000} a(**value)
functools還提供了豐富用於比較的API,在python2 中,在一個類中能夠定義 __cmp__() 方法,用於對象中的比較操做,python3 廢除了這樣的作法,由於提供了更加詳細的API方法,好比 __lt__() , __le__(), __eq__(),__ne__(),__gt__(),__ge__() 這些方法的含義以下:函數
- lt:less than 小於
- le:less than or equal to 小於等於
- eq:equal to 等於
- ne:not equal to 不等於
- ge:greater than or equal to 大於等於
- gt:greater than 大於
functools 提供了一個裝飾器,讓咱們不須要寫這麼多定義,只要寫一個,其餘定義也會加上去。 看一個簡單的例子spa
import functools @functools.total_ordering class MyObject(): def __init__(self,priority): self.priority = priority def __eq__(self,other): print('dengyu') return self.priority == other.priority def __lt__(self,other): return self.priority < other.priority if __name__ =="__main__": a = MyObject(1) print(dir(a))
在實際實驗中,加不加並無區別。僅做了解code
這是個有趣的裝飾器,傳入的參數被打上了hash,當下一次傳入的參數是同樣的時候,就會從cache中直接取出對應的值,而不須要進行從新的運算。一個簡單的例子orm
import functools @functools.lru_cache() def test_method(a,b): print("execute {} * {} = {}".format(a,b,a*b)) return a*b s = 0 for i in range(2): for j in range(2): s+=test_method(i,j) print(test_method.cache_info()) for i in range(2): for j in range(3): s+=test_method(i,j) print(test_method.cache_info()) print(s) # 4 說明該執行的仍是有執行,只不過是從cache中直接取出而已
對於python來講,很難去固定一個參數必須是什麼類型的,只能在具體的代碼裏面進行檢查,functools提供了一個裝飾器,能夠去作這樣的類型檢查.一個簡單的例子對象
import functools @functools.singledispatch def myfunc(args): print(args) @myfunc.register(list) def myfunc_list(args): for i in args: print("List item: {}".format(i)) if __name__ == "__main__": # 傳入兩個不一樣的類型參數,其處理邏輯也是不一樣 myfunc([1,2,3,6,4,5]) # 可是其調用的接口是同樣的。 這樣作的好處是能夠幫助咱們分離代碼邏輯 myfunc("Hello World")
輸出:接口
List item: 1 List item: 2 List item: 3 List item: 6 List item: 4 List item: 5 Hello World