什么是好的抽象?
比如這樣一個(gè)函數(shù):
def accumulate(combiner, base, n, term):
total, k=base, 1
while k<=n:
total,k = combiner(total, term(k)), k+1
return total
利用這個(gè)函數(shù)能夠構(gòu)建出不同的符合這個(gè)抽象的函數(shù)。
比如 將0-x間的不同特征的數(shù)相加:
term函數(shù)可以是平方,立方
def summation_using_accumulate(n, term):
return accumulate(add, 0, n, term)
相乘:
def product_using_accumulate(n, term):
return accumulate(mul, 1, n, term)
將0-x間的數(shù)過(guò)濾出來(lái)相加可以這樣子做:
def filtered_accumulate(combiner, base, pred, n,term):
def combiner_if(x,y):
if pred(y):
return combiner(x,y)
else:
return x
return accumulate(combiner_if, base, n, term)
利用一個(gè)高階函數(shù),pred是過(guò)濾的規(guī)則
比如只要偶數(shù)
odd = lambda x: x%2==1
filtered_accumulate(add, 0, odd, x, term)
再比如對(duì)一個(gè)函數(shù)多次調(diào)用
repeated(square, 2)(5) = square(square(5))
利用高階函數(shù)能夠很簡(jiǎn)單實(shí)現(xiàn)。
def repeated(f, n):
def inner(x):
nonlocal n
if n == 0:
return x
result = x
while n > 0:
result = f(result)
n -= 1
return result
return inner
但是仔細(xì)想想,似乎能夠用上面的那個(gè)函數(shù)來(lái)寫(xiě) 可以這樣做:
定義一個(gè)高階函數(shù)
def compose(f, g):
def h(x):
return f(g(x))
return h
def repeated(f, n):
return accumulate(compose, lambda x:x, n,lambda k:f)
發(fā)現(xiàn) 要進(jìn)行0-n次term計(jì)算,用compose來(lái)組合起來(lái) 都可以用accumuldate這個(gè)抽象
比如上面這個(gè)例子 對(duì)x進(jìn)行term計(jì)算,然后組合.
lambda 表達(dá)式,注意它是運(yùn)行時(shí)綁定的。
>>> a=3
>>> b=2
>>> c = lambda a,b:a+b
>>> b-=a
>>> c(a,b)
2
遞歸:
以常見(jiàn)的斐波那契數(shù)列來(lái)說(shuō)
樹(shù)形遞歸,復(fù)雜度最高,有很多的重復(fù)計(jì)算。
從f(1)=1開(kāi)始的。
def fib(n):
if n<2:
return n
return fib(n-1)+fib(n-2)
我們可以這樣子寫(xiě),利用數(shù)來(lái)保存中間變量,不用重復(fù)計(jì)算。
def fib2(a,b,n):
if n > 0:
return fib2(b,a+b,n-1)
return a
裝飾器:
@decorator
def func
相當(dāng)于decorator(func)
能夠用裝飾器做很多事情。比如:
定義一個(gè)memo緩存函數(shù),來(lái)優(yōu)化上面的fib
def memo(f):
cache = {}
def helper(*args):
if args not in cache:
cache[args]=f(args)
return cache[args]
return helper
利用了一個(gè)緩存來(lái)保存變量。
總結(jié) 要多思考建立好的函數(shù)抽象。
函數(shù)編碼原則:
- 函數(shù)名 稱應(yīng) 該小寫(xiě) , 以下劃 線分隔。 提倡描述性的名 稱。
- 函數(shù)名 稱通常反映解釋器 向參數(shù)應(yīng) 用 的操作( 例如 print 、 add 、 square ) , 或者結(jié)
果( 例 如 max 、 abs 、 sum ) 。 - 參數(shù)名 稱應(yīng) 小寫(xiě) , 以下劃 線分隔。 提倡單個(gè)詞的名 稱。
- 參數(shù)名 稱應(yīng) 該反映參數(shù)在函數(shù)中 的作用 , 并不僅僅是滿足的值的類型 。
- 當(dāng) 作用 非常明 確時(shí), 單個(gè)字母的參數(shù)名 稱可以接受, 但是永遠(yuǎn)不要使用 l ( 小寫(xiě) 的 L )
和 O ( 大寫(xiě) 的 o ) , 或者 I ( 大寫(xiě) 的 i ) 來(lái)避免和數(shù)字混淆。
函數(shù)設(shè)計(jì)原則
一個(gè)函數(shù)只完成一個(gè)功能,遵循dry原則。
寫(xiě)函數(shù)幫助文檔,利用doctest進(jìn)行測(cè)試。
調(diào)試的一些原則:
逐步測(cè)試,隔離錯(cuò)誤,追蹤到最小的代碼片。檢查假設(shè)。
來(lái)自http://www.97up.cn/post/83