1. 程式人生 > >python 學習彙總37:functools( tcy)

python 學習彙總37:functools( tcy)

functools 2018/9/13

--------------------------------------------------------------------------------------
1 模組簡介

用於高階函式:
    指那些作用於函式或者返回其它函式的函式,通常只要是可以被當做函式呼叫的物件就是這個模組的目標。

函式:
    cmp_to_key      將一個比較函式轉換關鍵字函式;
    partial         偏函式;
    reduce          同內建reduce函式;
    total_ordering,在類裝飾器中按照缺失順序,填充方法;
    update_wrapper,更新一個包裹(wrapper)函式,使其看起來更像被包裹(wrapped)的函式;
    wraps,         可用作一個裝飾器,簡化呼叫update_wrapper的過程;
---------------------------------------------------------------------------------
2 模組使用
2.1 cmp_to_key
    將老式的比較函式(comparison function)轉換為關鍵字函式(key function)
---------------------------------------------------------------------------------
2.2 偏函式functools.partial(funName,value,...)
    用途:
        函式引數值按設定值後固定使用
        # 把函式某些引數固定(設定預設值),返回新函式,呼叫這個新函式會更簡單
    引數:
        funName:函式物件
        value:*args和**kw這3個引數
    引數型別:
        a,b;a,b=None;*args(位置引數),kwargs(keyword引數)
----------------------------------------------------------------------------------

    用法:
    (1) 位置引數
    *******************************************
        from functools import partial
        def add(a, b=-1, c=-2):
            return (a,b,c)

        add(1, 2, 3)              # (1,2,3)

        add_1 = partial(add, 1)
        add_1(2, 3)               # (1,2,3)
        add_2= partial(add,1,2)
        add_2(3)                  # (1,2,3)
    *******************************************
        # 轉換二進位制字串
        def int_1(x, base=2):
            return int(x, base)

        int_1('1000000',   base=2)  # 64

        int_2 = functools.partial(int_1, base=2)
        int_2('1000000')  # 64
            # 相當於:kw = { 'base': 2 };int_1('1000000', **kw)

        int_2('1000000', base=10)  # 1000000
        *******************************************
        max_1 = functools.partial(max, 10)  # 把10作為*args一部分自動加到左邊
        max_1(5, 6, 7)  # 10
            # 相當於:args = (10, 5, 6, 7);max(*args);
        *******************************************

    (2) 位置引數和keyword引數
        import functools
        def add(*args, **kwargs):
            return "args={};kwargs={}".format(args,kwargs)

        print(add(1, 2))
        add_1 = functools.partial(add,1,2,3,a=10,b=20,c=30)
        print(add_1(4,5,d=40,e=50))
        # args=(1, 2);kwargs={}
        # args=(1, 2, 3, 4, 5);kwargs={'a': 10, 'b': 20, 'c': 30, 'd': 40, 'e': 50}
----------------------------------------------------------------------------
2.3 reduce(f(x,y),list)#函式 f 必須接收兩個引數
    # 用途: 對list的每個元素反覆呼叫函式f,並返回最終結果值。
    # 原理: 將前2個數據相加作為第一個結果,然後將第一個結果和第三個值相加作為第2個結果,依次類推。
        
    import functools
    functools.reduce(lambda x,y:x+y,range(0,6))# 15
            
#y0=x0+x1=0+1=1
#y1=y0+x2=1+2=3
#y2=y1+x3=3+3=6
#y3=y2+x4=6+4=10
#y4=y3+x5=10+5=15
        
----------------------------------------------------------------------------
2.4 total_ordering
    是一個類裝飾器,補充其餘的比較方法
    類必須至少定義 __lt__(), __le__(),__gt__(),__ge__()其中一個,同時,提供 __eq__()方法
    -
    例項:
        from functools import total_ordering

        @total_ordering
        class Student:
            def __init__(self, firstname, lastname):
                self.firstname = firstname
                self.lastname = lastname

            def __eq__(self, other):
                return ((self.lastname.lower(), self.firstname.lower()) ==
                        (other.lastname.lower(), other.firstname.lower()))
            def __lt__(self, other):
                return ((self.lastname.lower(), self.firstname.lower()) <
                        (other.lastname.lower(), other.firstname.lower()))
        -
        a = Student("ab", "cd")
        b = Student("ab", "cd")
        c = Student("ab", "ce")
        print("a<b", a<c)#True
        print("a<b", c>b)#True
        print( "b", a==b)#True
-
----------------------------------------------------------------------------
2.5 wraps 用作一個裝飾器,簡化呼叫update_wrapper過程.

# 等價於呼叫
partial(update_wrapper, wrapped = wrapped, assigned=assigned,updated=updated)

# 例項:
from functools import wraps
import time

def my_decorator(f):
print("1.my_decorator start...")
@wraps(f)
def wrap(*args, **kwargs):
print( "2.decorated func called start == > ")
return f(*args, **kwargs)
print("3.my_decorator end")
return wrap

@my_decorator
def MyFun():
"""MyFun doc writec by tcy shanghai 2018/11/15."""
print ("4.MyFun start...")
time.sleep(2)
print("5.MyFun end.")

# 測試
MyFun()
print('6.MyFun.doc=',MyFun.__doc__)
print('7MyFun.name=',MyFun.__name__)

# 輸出結果

# 1.my_decorator start...
# 3.my_decorator end
# 2.decorated func called start == >
# 4.MyFun start...
# 5.MyFun end.
# 6.MyFun.doc= MyFun doc writec by tcy shanghai 2018/11/15.
# 7MyFun.name= MyFun

----------------------------------------------------------------------------