python函數式編程之返回函數、匿名函數、裝飾器、偏函數學習


python函數式編程之返回函數

高階函數處理可以接受函數作爲參數外,還可以把函數作爲結果值返回。

  • 函數作爲返回值

    def laxy_sum(*args):
        def sum():
            ax = 0;
            for n in args:
                ax = ax + n;
            return ax;
        return sum;
    
    print(laxy_sum(1, 3, 5, 7));
    # <function laxy_sum.<locals>.sum at 0x000001F2E3272F28>返回一個函數而不是一個值
    

    在這個函數中,內部函數sum可以引用外部函數laxy_sum的參數和局部變量,當外部函數返回函數sum時,相關參數和變量都保存在返回的函數中,這種情況稱爲“閉包”個人覺得和JavaScript的閉包很相似,這種程序結構擁有極大的威脅。
    當我們調用lazy_sum時,每次調用都會返回新的函數,即使傳入相同的參數。

  • 閉包
    當一個函數返回了一個函數後,其內部的局部變量還被新函數引用。返回的函數並沒有立即執行,而是直到調用了外部函數才執行

python函數式編程之匿名函數

當我們在傳入函數時,有時候不需要顯式的定義函數,而是直接傳入匿名函數。
匿名函數就是沒有函數名的函數,python用關鍵字lambda表示匿名函數,冒號前面的x表示函數的參數

#匿名函數
p = list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6]));
print(p);
# [1, 4, 9, 16, 25, 36]

匿名函數有個限制,就是只能有一個表達式,不用寫return,返回值就是該表達式的結果。

python函數式編程之裝飾器

由於函數也是一個對象,函數對象也可以賦值給變量,所以我們可以通過變量也能調用函數。

def now():
    print('2017-11-22');

f = now;
print(f());# 2017-11-22

函數對象有一個屬性name屬性,可以拿到函數的名字:像上面的例子就可以用 f.name取到函數的名字now

在代碼運行期間動態增加功能的方式,稱之爲“裝飾器”(Decorator)。如,在函數now調用前後自動打印日誌,但又不希望修改now()函數的定義。裝飾器本質上是一個幹返回函數的高階函數。

def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__);
        return func(*args, **kw);
    return wrapper;

@log
def now():
    print('2017-11-22');

print(now());
# call now():
# 2017-11-22

Python的@語法後續

python函數式編程之偏函數

  • 簡單理解
    如int()函數可以把字符串轉換成整數形式:

    print(int("1234"));#字符串轉換成整數
    

    int函數還提供了base參數,用來把字符串轉換成N進制的數,默認是10.

    print(int("12345", base=8));
    

    但是當我們要進行很多的值轉換的時候,一個個傳入函數的話,就會很低效,那麼我們就可以編寫一個這樣的函數,讓他能實現我們的想法。

    def int2(x, base=2):
        return int(x, base)
    
    print(int2("100001"));#33
    print(int2("1101110"));#110
    

    向上面這樣我們就不用多次輸入int(x, base=n),python的functools.partial就幫我們創建了一個偏函數,不需要我們編寫函數int2,可以直接創建一個int2函數:

    #偏函數
    import functools;
    int2 = functools.partial(int, base=2);
    print(int2("11101"));#29
    

    所以,functools.partial的作用就是,把一個函數的某些參數設置默認值,返回個新的函數,調用這個新函數會更簡單。但也可以傳入其他的值,如:int2(“10010”, base=10);

  • 總結
    當我們函數參數個數很多,需要簡化時,我們可以使用python的functools.partial來創建一個偏函數來固定一些參數,使得我們在使用新函數的時候更加方便。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章