python可以用很多方式運行起來:
1. 使用控制檯,鍵入python,即可進入python解釋器,然後每一句都會被解釋執行
2. 使用IDE,同樣是解釋器形式
3. 使用文本編輯器寫一系列代碼保存,並在控制檯進入保存的目錄,鍵入 python xxx.py,翻譯並執行
4. 用IDE提供的編輯器,寫完之後run,效果與3一樣。
如果一個文件裏面全部只有定義的函數,如果執行該程序,會有什麼效果呢?
#test1.py
def compare_boy(b1,b2):
if(b1[0]<b2[0]):
return -1
elif(b1[0]>b2[0]):
return 1
return 0
如果使用方式1、方式2執行,該函數的定義會被存儲下來,之後的語句可以使用,而使用3、4方式,運行結束後沒有任何效果。
開始
函數式編程是一種編程範式,其主要內涵是隻有函數沒有變量的抽象編程思想。python不是函數式編程語言,但是也支持一些函數式編程的功能。
1. 函數作爲參數——高階函數
函數在定義後,函數名可以作爲變量使用,也可以作爲參數傳遞到另外一個函數中。接受函數作爲參數的函數稱之爲高階函數。
def cut(list_b,cmp,pos):
l = []
n = len(list_b)
b = list_b[pos]
l = list_b[0:pos]+list_b[pos+1:]
left = [i for i in l if(cmp(b,i)<0)]
right = [i for i in l if(cmp(b,i)>=0)]
left.append(b)
return left+right
這個函數功能是把列表list_b的pos位置處元素提出來,然後比它小的放在右邊,比它大的放在左邊。
[i for i in l if(cmp(b,i)<0)]:是生成列表的一種方式,方法是對l進行遍歷,取出滿足if中條件的元素。
left+right:列表重載了+運算符,可以作爲連接操作。
這裏把cmp視爲一個函數使用,我們可以傳入之前的函數與參數進行測試:
boy1 = [3,'Jack','m',15]
boy2 = [1,'Mark','m',19]
boy3 = [2,'Tim','m',25]
boys = (boy1,boy2,boy3)
print cut(boys,compare_boy,0)
2. 函數作爲返回值——閉包
函數能作爲參數傳入,也自然能作爲返回值返回,但不是說返回函數的函數就是閉包。
看一個例子來理解閉包的概念:
def addlistfun(cho):
list = []
def add(it):
list.append(it)
print list
return list
if(cho==1):
list = list + ['this list is for fun']
return add
else:
list = list + ['this is another']
return add
這裏在函數的內部定義了函數,在python中這是允許的,在c++中在函數中定義函數是未定義行爲(匿名函數除外)。
這個函數內部的函數使用了其外部函數的變量list,這種看似奇怪的程序結構稱爲閉包。
當這個內部函數被作爲返回值返回時,其所有使用的外部函數的變量會綁定在該函數上,其初始值爲返回時的值,而且每次函數返回的值是相互獨立的。因此上面程序的測試結果中,選擇cho參數不同的會有不同的表頭。
3 . 匿名函數與偏函數
匿名函數的名字是lambda,使用方法如下:
addf = lambda(list,item):list.append(item)
匿名函數只能寫一句表達式,且該表達式的值就是其返回值。(append()方法的返回值是None)
偏函數神似c++中的bind函數,作用是將一個值綁定在函數的參數上。使用前需要import functools
import functools
l = []
addf2 = functools.partial(addf,list = l)
addf2(12)
但這句話會發生錯誤,經過反覆測試推理,有兩個錯誤:
1. 參數是不能綁定在非綁定參數之前,即上面的list要放在item之後。這個可以理解,相當於c++中缺省參數不能放在非缺省之前。
2. 匿名函數不能用這種方法綁定,原因未知。
修改:改爲一般定義的函數,調換參數位置。測試成功。
(
其他的推理(錯誤):
傳遞的是字面值——通過傳遞默認參數的方式推翻
參數值需要特殊標識——並不需要
……
)
參考資料:
JS中的閉包:
http://kb.cnblogs.com/page/110782/
廖雪峯教程:
http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386819893624a7edc0e3e3df4d5d852a352b037c93ec000
python傳遞值還是傳遞引用:
http://www.cnblogs.com/loleina/p/5276918.html