引言
Functional Programming(函數式編程)的概念最早起源于LISP,由約翰·麥卡錫在1958年創立,最早提出了自動垃圾回收的理念,這一理念現在也被Python/Java/Ruby等多種語言借鑒。發展到今天,LISP已經衍生出了多種方言。相比面向對象編程,函數式編程的一大優勢就是Immutable Data(數據不可變),就是不依賴于外部的數據,而且也不改變外部數據的值,這種思想可以大大減少我們代碼的Bug,而且函數式編程也支持我們像使用變量一樣使用函數。Python作為面向對象語言,也提供了對于函數式編程的支持,雖然并不是那么純粹,而且也不支持尾遞歸優化。
lambda的使用
lambda即匿名函數,合理地使用lambda不僅可以減少我們的代碼量,而且也可以更好地描繪代碼邏輯,比如現在我們有下面這樣一個函數。
>>> def f(x):
... return x + x
# 調用這個函數
>>> f(2)
4
這個函數如果我們用lamda改寫的話,只要一行代碼就夠了。
# lambda后面的x表示lambda函數要接收的參數,x + x表示lambda函數所要返回的值
>>> f = lambda x: x + x
# 可以看到f現在也是一個函數對象
>>> f
# 調用lambda函數
>>> f(2)
4
map的使用
map(function, iterable)接收兩個參數,第一個參數代表的是接收一個函數,第二個參數代表的是接收一個iteralbe類型的對象,比如list。
map函數的原理是: 1.每次從iterable中取出一個參數,2.將這個參數傳遞給我們的函數,3.然后函數返回的值加入一個list(這種說法不準確,只是為了幫助大家理解,后面我會解釋)。等所有的iterable對象遍歷完,map就把這個list返回給我們的調用者。下面我們直接通過實例來了解一下map的用法。
example1
# 還是用我們上面那個lambda的例子
>>> function = lambda x: x + x
# 定義一個iterable對象list(列表)
>>> iterable = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 函數fucntion每次從iterable中取出一個參數x,然后function返回x + x的值,
# 并將返回值加入一個新建的list,等將iterable遍歷完,map就將這個新建的list返回。
>>> v = map(function, iterable)
# 注意上面的說法并不準確,只是為了幫助大家理解,其實map返回的是一個map對象,并不是list
>>> v
example2
對于map的第二個參數,我們也可以傳遞一組函數列表進去,也就是說列表中間包含多個函數對象。
>>> multiply = lambda x: x * x
>>> add = lambda x: x + x
>>> funcs = [multiply, add]
>>> list(map(lambda f: f(1), funcs))
[1, 2]
reduce的使用
與map一樣,reduce(function, iterable)也接收兩個參數,第一個參數代表的是接收一個函數,第二個參數代表的是接收一個iteralbe類型的對象,比如list。不過不同的地方在于reduce中的這個函數必須要接收兩個參數,下面我們來通過求一個list(列表)累加和的例子來了解一下reduce的用法。
from functools import reduce
# 使用lambda定義一個函數,函數的作用是接收兩個參數,然后返回兩個參數之和
>>> function = lambda x, y: x+y
>>> iterable = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 函數function每次接收兩個參數,除第一次外每次從iterable中取一個元素作為一個參數
# 另外一個參數取自上一次function返回的值
>>> reduce(function, iterable)
45
filter的使用
和map/reduce類似,filter(function, iterable)一次也接收兩個參數,一個參數是函數,另外一個參數是iterable對象,從名字也可以看出,filter用于過濾iterble對象,比如說list(列表)。
它的原理是每次從iterable對象中取出一個元素作用于我們的function,如果function返回True就保留該元素,如果返回False就刪除該元素。下面我們通過一個實例來看一下filter的用法。
# 定義一個函數,如果接收的字符s為空,那么返回False,如果為非空,那么返回True
>>> function = lambda s : s and s.strip()
>>> iterable = ['AJ', ' ', 'Stussy', '', 'CLOT', 'FCB', None]
>>> filter(function, iterable)
>>> list(filter(function, iterable))
['AJ', 'Stussy', 'CLOT', 'FCB']
裝飾器
裝飾器(decorator)是一種高級Python語法。裝飾器可以對一個函數、方法或者類進行加工。合理地使用裝飾器可以減少我們的代碼量以及提高程序的可讀型,在很多Python框架中,比如Django中我們可以大量看到裝飾器的身影。
>>> def add(x, y):
... return x + y
...
>>> def multiply(x, y):
... return x * y
...
現在我們有上面兩個函數,分別用來求加法和乘法,但是現在我們覺得功能不夠,想在返回結果前添加一些輸出語句,一般來說我們要重構兩個函數,就向下面這樣。
>>> def add(x, y):
... print("input:", x, y)
... return x + y
...
>>> def multiply(x, y):
... print("input:", x, y)
... return x * y
...
如果使用裝飾器我們可以像下面這樣做,雖然現在我們這種情形看起來使用裝飾器并沒有什么優勢,但是如果我們要添加的不止一條打印功能,以及除了add/multiply我們還有minus/divide等函數,這個時候裝飾器的威力就體現出來了,我們只用修改一處代碼即可,這樣不僅提高了程序的可讀性而且也為以后我們重構代碼省去了很多的工作量。
def decorator(F):
def new_function(x, y):
print("input:", x, y)
return F(x, y)
return new_function
@decorator
def add(x, y):
return x + y
@decorator
def multiply(x, y):
return x * y
評論
查看更多