python學習筆記(三)運行環境、函數式

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章