5-functools模塊

functools

functools 包含了用於建立裝飾函數,啓動面向切面的編程,超出面向對象編程範圍的代碼複用,同時提供了裝飾函數用於豐富的快捷比較的API, partial 模塊還建立了包含函數參數的函數引用,也就是偏函數python

partial 偏函數

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)

Comparison

functools還提供了豐富用於比較的API,在python2 中,在一個類中能夠定義 __cmp__() 方法,用於對象中的比較操做,python3 廢除了這樣的作法,由於提供了更加詳細的API方法,好比 __lt__() , __le__(), __eq__(),__ne__(),__gt__(),__ge__() 這些方法的含義以下:函數

  1. lt:less than 小於
  2. le:less than or equal to 小於等於
  3. eq:equal to 等於
  4. ne:not equal to 不等於
  5. ge:greater than or equal to 大於等於
  6. 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

lru_cache

這是個有趣的裝飾器,傳入的參數被打上了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
相關文章
相關標籤/搜索