天天看點

Python之functools子產品使用方法

functools

reduce方法:

    reduce方法,顧名思義就是減少

    reduce(function,sequence[,initial]=>value)

    可疊代對象不能為空;初始值沒提供就在可疊代對象中取一個元素

from functools import reduce
nums = [6,9,4,2,4,10,5,9,6,9]
print(nums)
[6, 9, 4, 2, 4, 10, 5, 9, 6, 9]
print(sum(nums))
64
print(reduce(lambda val,x:val + x,nums))
64
print(reduce(lambda val,x:val - x,nums))
-52
           

partial方法:

    偏函數,把函數部分的參數固定下來,相當于為部分的參數添加了一個固定的預設值,形成一個新的函數并傳回

    從partial生成的新函數,是對原函數的封裝

print(newadd(7))
12
print(newadd(7,y = 6))
13
print(newadd(y=10,x = 6))
16

import inspect
print(inspect.signature(newadd))
(x, *, y=5) -> int  #被偏函數定義後,形參将變為keyword-only
           
import functools

def add(x,y,*args,**kwargs) -> int:
    print(args)
    return x + y
newadd = functools.partial(add,1,3,6,5)
print(newadd(7))
(6, 5, 7)
4

print(newadd(7,10))
(6, 5, 7, 10)
4
#print(newadd(7,8,y = 20,x = 26)) #不可以這樣定義
print(newadd())
(6, 5)
4

import inspect
print(inspect.signature(newadd))
(*args, **kwargs) -> int
           
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)
9
           

@functools.lru_cache(maxsize=128,typed=False):

    Least-recently-used裝飾器。lru,最近最少使用。cache緩存

    如果maxsize設定為None,則禁用LRU功能,并且緩存可以無限制增長。當maxsize是二的幂時,LRU功能執行得最好

    如果typed設定為True,則不同類型的函數參數将單獨緩存。例如,f(3)和f(3.0)将視為具有不同結果的不同調用

import functools
import time
@functools.lru_cache()
def add(x,y,z=3):
    time.sleep(z)
    return x + y

add(4,5)
9
add(4.0,5)
9
add(4,6)
10
add(4,6,3)
10
add(6,4)
10
add(4,y=6)
10
add(y=6,x=4)
10
           

lru_cache裝飾器:

functools._make_key((4,6,3),{},False)
[4, 6, 3]

通過一個字典緩存被裝飾函數的調用和傳回值

functools._make_key((4,6,3),{},False)
[4, 6, 3]

functools._make_key(tuple(),{'z':3,'x':4,'y':6},False)
[<object at 0x7ff7d24010b0>, 'z', 3, 'x', 4, 'y', 6]

functools._make_key((),{'z':3,'x':4,'y':6},False)
[<object at 0x7ff7d24010b0>, 'z', 3, 'x', 4, 'y', 6]

functools._make_key((),{'z':3,'x':4,'y':6},True)
[<object at 0x7ff7d24010b0>, 'z', 3, 'x', 4, 'y', 6, int, int, int]
           

lru_cache裝飾器:

    斐波那契數列遞歸方法的改造

import functools
@functools.lru_cache() #maxsize=None
def fib(n):
    return 1 if n< 3 else fib(n-1) + fib(n-2)

print([fib(i+1) for i in range(35)])
[1, 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]
           

lru_cache裝飾器應用:

    使用前提:

        同樣的函數參數一定得到同樣的結果

        函數執行時間很長,且要多次執行

        本質是函數調用的參數=》傳回值

    缺點 :

        不支援緩存過期,key無法過期、失效

        不支援清楚操作

        不支援分布式,是一個單機的緩存

适用場景,單機上需要空間換時間的地方,可以用緩存來将計算變成快速的查詢

繼續閱讀