python總結(五) 函式式程式設計plus

2021-09-24 16:23:31 字數 3841 閱讀 5860

1.高階函式除了可以接受函式作為引數外,還可以把函式作為結果值返回。

def lazy_sum(*args):

def sum():

ax = 0

for n in args:

ax = ax + n

return ax

return sum

>>> f = lazy_sum(1, 3, 5, 7, 9)

>>> f()

注意到返回的函式在其定義內部引用了區域性變數args,所以,當乙個函式返回了乙個函式後,其內部的區域性變數還被新函式引用,所以,閉包用起來簡單,實現起來可不容易。

返回閉包時牢記一點:返回函式不要引用任何迴圈變數,或者後續會發生變化的變數。 

如果一定要引用迴圈變數怎麼辦?方法是再建立乙個函式,用該函式的引數繫結迴圈變數當前的值,無論該迴圈變數後續如何更改,已繫結到函式引數的值不變:

def count():

def f(j):

def g():

return j*j

return g

fs =

for i in range(1, 4):

return fs

1.計算f(x)=x2時,除了定義乙個f(x)的函式外,還可以直接傳入匿名函式:

>>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))

[1, 4, 9, 16, 25, 36, 49, 64, 81]

關鍵字lambda表示匿名函式,冒號前面的x表示函式引數。

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

2.也可以把匿名函式賦值給乙個變數,再利用變數來呼叫該函式:

>>> f = lambda x: x * x

>>> f

at 0x101c6ef28>

>>> f(5)

25

3.也可以把匿名函式作為返回值返回,比如:

def build(x, y):

return lambda: x * x + y * y

1.函式也是乙個物件,而且函式物件可以被賦值給變數,所以,通過變數也能呼叫該函式

2.函式物件有乙個__name__屬性,可以拿到函式的名字:

def now():

... print('2015-3-25')

f = now

>>> f()

2015-3-25

>>> now.__name__

'now'

>>> f.__name__

'now'

3.我們要增強now()函式的功能,比如,在函式呼叫前後自動列印日誌,但又不希望修改now()函式的定義,這種在**執行期間動態增加功能的方式,稱之為「裝飾器」(decorator)。本質上,decorator就是乙個返回函式的高階函式。所以,我們要定義乙個能列印日誌的decorator

def log(func):

print('call %s():' % func.__name__)

return func(*args, **kw)

觀察上面的log,因為它是乙個decorator,所以接受乙個函式作為引數,並返回乙個函式。我們要借助python的@語法,把decorator置於函式的定義處 

@log

def now():

print('2015-3-25')

呼叫now()函式,不僅會執行now()函式本身,還會在執行now()函式前列印一行日誌:  

call now():

2015-3-25

4.如果decorator本身需要傳入引數,那就需要編寫乙個返回decorator的高階函式,寫出來會更複雜。比如,要自定義log的文字:

def log(text):

def decorator(func):

print('%s %s():' % (text, func.__name__))

return func(*args, **kw)

return decorator

這個3層巢狀的decorator用法如下:

@log('execute')

def now():

print('2015-3-25')

執行結果:

>>> now()

execute now():

2015-3-25

>>> now.__name__
import functools

def log(text): #該函式主要作用是傳參

def decorator(func): #該函式是裝飾器

@functools.wraps(func) #該語句的作用是:不讓原函式名改變

print('%s %s():' % (text, func.__name__))

return func(*args, **kw)

return decorator

import time, functools

def metric(fn):

@functools.wraps(fn)

start=time.time()

re=fn(*args,**kw)

end=time.time()

print('%s executed in %s ms' % (fn.__name__, end-start))

return fn(*args,**kw)

@metric

def fast(x, y):

time.sleep(0.0012)

return x + y;

s = fast(56, 23)

print (s)

5.總結:在物件導向(oop)的設計模式中,decorator被稱為裝飾模式。oop的裝飾模式需要通過繼承和組合來實現,而python除了能支援oop的decorator外,直接從語法層次支援decorator。python的decorator可以用函式實現,也可以用類實現。decorator可以增強函式的功能,定義起來雖然有點複雜,但使用起來非常靈活和方便。

1.functools.partial的作用就是,把乙個函式的某些引數給固定住(也就是設定預設值),返回乙個新的函式,呼叫這個新函式會更簡單。建立偏函式時,實際上可以接收函式物件、*args**kw這3個引數

import functools

int2 = functools.partial(int, base=2)

max2 = functools.partial(max, 10)

函式式程式設計(五)

如果你前面都看完了跟到了這裡,我只能說你很棒棒,不過我不得不說,這才剛剛開始。前面我們已經知道如何書寫函式式的程式了,但是我們還沒提到控制流 control flow 異常處理 error handling 非同步操作 asynchronous actions 和狀態 state 呢?容器為函式式程...

函式式程式設計總結

尾遞迴解決的是棧的記憶成本,更好防止堆疊溢位。遞迴在兩種情況下會掛 一是沒有結束條件 二是堆疊記憶體超過了最大限制。1 柯里化 柯里化是一種 預載入 函式的方法,通過傳遞較少的引數,得到乙個已經記住了這些引數的新函式,某種意義上講,這是一種對引數的 快取 是一種非常高效的編寫函式的方法。2 高階函式...

函式式程式設計總結

函式式程式設計是圍繞高階函式進行的,設計的核心在於高階函式的設計。1 函式式程式設計通過函式的復合生成更大的結構 2 函式的操作分為分解和復合 分解即為柯里化,可以分為偏函式分解和徹底分解。復合即為待定係數和呼叫約定。3 函式的運算最終轉化為代數運算。4 monad的本質是簡化版的物件,與閉包類似 ...