函式式程式設計的乙個特點就是,允許把函式本身作為引數傳入另乙個函式,還允許返回乙個函式。
變數可以指向函式
>>> f = abs
>>> f(-10)
10
函式名也是變數
>>> abs = 10
>>> abs(-10)
traceback (most recent call last):
file "", line 1, in typeerror: 'int' object is not callable
傳入函式
乙個函式可以接收另乙個函式作為引數,這種函式就稱之為高階函式。
def add(x, y, f):
return f(x) + f(y)
接收兩個引數,乙個是函式,乙個是序列,map將傳入的函式依次作用到序列的每個元素,並把結果作為新的list返回。
>>> def f(x):
... return x * x
...>>> map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
[1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])
['1', '2', '3', '4', '5', '6', '7', '8', '9']
把乙個函式作用在乙個序列[x1, x2, x3...]上,這個函式必須接收兩個引數,reduce把結果繼續和序列的下乙個元素做累積計算。
'reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)'
>>> def add(x, y):
... return x + y
...>>> reduce(add, [1, 3, 5, 7, 9])
25
接受乙個函式和乙個序列,將傳入的函式作用於每乙個元素,然後根據返回值是true還是false,決定是否保留該元素。
def is_odd(n):
return n % 2 == 1
filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])
# 結果: [1, 5, 9, 15]
接收乙個比較函式來實現自定義的排序。
def reversed_cmp(x, y):
if x > y:
return -1
if x < y:
return 1
return 0
>>> sorted([36, 5, 12, 9, 21], reversed_cmp)
[36, 21, 12, 9, 5]
函式作為返回值
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
當呼叫lazy_sum()時,返回的並不是求和結果,而是求和函式:
>>> f = lazy_sum(1, 3, 5, 7, 9)
>>> f
呼叫函式f時,才真正計算求和的結果:
>>> f()
25
關鍵字lambda表示匿名函式,冒號前面的x表示函式引數。
匿名函式只能有乙個表示式,不用寫return,返回值就是該表示式的結果。
函式沒有名字,不必擔心函式名衝突。此外,匿名函式也是乙個函式物件,也可以把匿名函式賦值給乙個變數。
>>> map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])
[1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> f = lambda x: x * x
>>> f
at 0x10453d7d0>
>>> f(5)
25
在**執行期間動態增加功能的方式,稱之為「裝飾器」(decorator)。本質上,decorator就是乙個返回函式的高階函式。
ps:函式物件有乙個__name__屬性,可以拿到函式的名字(f.__name__)。
def log(func):
print 'call %s():' % func.__name__
return func(*args, **kw)
@log
def now():
print '2013-12-25'
>>> now()
call now():
2013-12-25
相當於now=log(now)
如果decorator本身需要傳入引數,再套一層定義即可。
def log(text):
def decorator(func):
print '%s %s():' % (text, func.__name__)
return func(*args, **kw)
return decorator
@log('execute')
def now():
print '2013-12-25'
>>> now()
execute now():
2013-12-25
相當於now=log('execute')(now)
返回函式的名字是最內層的,所以當前函式的名字會出錯。python內建的functools.wraps能過實現命名,在最內層的函式外加上@functools.wraps(func)即可。
import functools
def log(func):
@functools.wraps(func)
print 'call %s():' % func.__name__
return func(*args, **kw)
#帶引數的decorator
import functools
def log(text):
def decorator(func):
@functools.wraps(func)
print '%s %s():' % (text, func.__name__)
return func(*args, **kw)
return decorator
int()函式提供額外的base引數,預設值為10。如果傳入base引數,就可以做n進製的轉換。
int('12345', base=8)
那如果想要乙個轉二進位制的函式int2()呢?functools.partial可以幫助我們建立乙個偏函式,不需要我們自己定義int2()。
>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64>>> int2('1010101')
85
簡單總結functools.partial的作用就是,把乙個函式的某些引數給固定住(也就是設定預設值),返回乙個新的函式。建立偏函式時,實際上可以接收函式物件、*args和**kw這3個引數。 廖雪峰Python教程學習筆記4 函式式程式設計
函式式程式設計就是一種抽象程度很高的程式設計正規化,其乙個特點是允許把函式本身作為引數傳入另乙個函式,還允許返回乙個函式!把函式作為引數傳入,這樣的函式稱為高階函式,函式式程式設計就是指這種高度抽象的程式設計正規化。既然變數可以指向函式,函式的引數能接收變數,那麼乙個函式就可以接收另乙個函式作為引數...
python學習筆記之函式式程式設計
把運算過程寫成函式巢狀呼叫的表示式 例如數學表示式 1 2 3 4 面向過程 a 1 2 b a 3 c b 4 函式式 result subtract multiply add 1,2 3 4 add 1,2 multiply 3 subtract 4 merge 1,2 3,4 sort sea...
python學習之dedecms exp編寫
針對織夢5.7 sp1遠端檔案包含getshell exp編寫,漏洞分析請檢視網上分析,不再贅述。exp coding utf 8 import requests import time def dada url url index url install index.php khtml,like ...