6 函式(一)
前面寫的程式都是很小的,假設我們要編寫乙個很大的程式,並且要重複使用很多遍相同的**,直觀的想法,自然就是把這些**裝到乙個「箱子」裡,給這個「箱子」編上號,等到用的時候,告訴電腦「箱子」裡面的就是所需要的**。
函式就可以實現這樣的功能。函式是python中最主要也是最重要的**組織和復用手段。
假設我們想求出兩個數相加的結果,就可以寫如下的函式:
in [1]: def add(x,y):
...: z = x + y
...: return(z)
其中def是宣告函式的關鍵字,是必須要寫的;add是函式的名稱;在圓括號裡面的x,y是引數,可以理解為數學函式的自變數,並且圓括號也是必須寫的;z可以理解為函式的因變數;最後,我們通過return函式,將結果z輸出來。
如果我們要求1+2,20+30的值,就可以這樣寫:
in [2]: add(1,2)
out[2]: 3
in [3]: add(20,30)
out[3]: 50
相當於我們把1和2代到自變數那裡,就可以得到了結果。需要注意的是,add函式只有兩個引數,如果帶入引數的個數不為2,會引起錯誤:
in [4]: add(1,2,3)
typeerror traceback (most recent call last)
in ()
----> 1 add(1,2,3)
typeerror: add() takes 2 positional arguments but 3 were given
6.1 引數
從前面可以看到,引數相當於數學上函式的自變數。python也有很多種引數的寫法,通過不同的引數,可以實現不同的功能。位置引數
前面例子使用的引數就是位置引數。位置引數的位置很重要,比它的名稱要重要得多。我們考慮下面兩個函式:
in [5]: def divide1(a,b):
...: return(a/b)
in [6]: def divide1(b,a):
...: return(a/b)
我們定義了兩個函式divide1和divide2,除了圓括號中引數a和b的位置,它們都是一樣的。接下來我們把數字1和2帶入:
in [10]: divide1(1,2)
out[10]: 0.5
in [11]: divide2(1,2)
out[11]: 2.0
在函式divide1裡面,a和數字1的位置是一樣的,此時a等於1;b和數字2的位置是一樣的,此時b等於2。所以結果為1/2,即0.5。對於divide2來說,a等於2,b等於1,結果自然為2。關鍵字引數
如果引數個數很多的話,引數的位置我們很難記住。為了簡化工作,我們也可以指定引數的名稱:
in [12]: divide2(a=1,b=2)
out[12]: 0.5
我們指定a的值為1,b的值為2,這樣divide2的結果也是0.5了。
像這樣使用名稱指定的引數就是關鍵字引數,主要的優點是有助於澄清各個引數的作用,並且引數的位置不一樣也不影響結果。
in [13]: divide2(b=2,a=1)
out[13]: 0.5
關鍵字引數最大的優點是可以指定預設值。考慮新的函式divide3:
in [14]: def divide3(a=1,b=1):
...: return(a/b)
在這個函式裡面,我們預設a和b的值為1,如果我們不往函式裡面輸入值的話,python就按照a和b的值為1進行計算:
in [16]: divide3()
out[16]: 1.0
但如果沒有指定預設值,就會報錯:
in [17]: divide2()
typeerror traceback (most recent call last)
in ()
----> 1 divide2()
typeerror: divide2() missing 2 required positional arguments: 'b' and 'a'可變引數
在前面我們知道,值的個數和引數個數不一樣就會報錯。但是如果在某個問題裡面,引數個數是不固定的怎麼辦。這就要用到可變引數了。
我們考慮求幾個數的和,但數字的個數是不固定的。
如果我們括號裡面寫成位置引數,只需要定義乙個引數,然後在引數前面寫個*號:
in [22]: def add2(*number):
...: sum = 0
...: for i in number:
...: sum = sum + i
...: return(sum)
in [23]: add2(1,2,3)
out[23]: 6
in [24]: add2(1,2,3,4)
out[24]: 10
工作原理是這樣的:python把我們輸入的任意的引數轉化為元組,我們利用元組的操作,就可以得到結果了。
對於關鍵字引數,需要在引數前面寫**號:
in [25]: def add3(**number):
...: sum = 0
...: for i in number.values():
...: sum = sum + i
...: return(sum)
in [26]: add3(a=1,b=2,c=3)
out[26]: 6
python把我們輸入的關鍵字引數轉化為字典,其中引數名稱為字典的鍵,引數值為字典的值。我們再利用字典的相關操作,就可以得到結果了。
需要注意的是,這兩種可變引數不可混用,否則會報錯:
in [27]: add2(a=1,b=2,c=3)
typeerror traceback (most recent call last)
in ()
----> 1 add2(a=1,b=2,c=3)
typeerror: add2() got an unexpected keyword argument 'a'
in [28]: add3(1,2,3)
typeerror traceback (most recent call last)
in ()
----> 1 add3(1,2,3)
typeerror: add3() takes 0 positional arguments but 3 were given引數組合
前面介紹的幾種引數是可以混用的,但是順序是固定的,必須是(從前往後):位置引數、關鍵字引數、可變引數(對應位置引數)、可變引數(對應關鍵值引數),在使用函式的時候,python自動按照引數位置和引數名把引數帶入到函式裡面。
考慮如下的函式:
in [29]: def f1(a,b,c=1,*args,**kw):
...: print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
這個函式裡面有五個不同型別的引數,並分別輸出引數結果。對於不同的賦值方式,也就有不同的結果:
in [30]: f1(1,2,3,4,5)
a = 1 b = 2 c = 3 args = (4, 5) kw = {}
in [31]: f1(1,2,3,4,e = 5)
a = 1 b = 2 c = 3 args = (4,) kw =
in [32]: f1(1,2,3)
a = 1 b = 2 c = 3 args = () kw = {}
6.2 返回多個值
這也是python乙個比較特別的功能。在前面的例子當中,函式的結果只有乙個,但我們也可以輸出多個結果。記得沒錯的話,r語言並沒有這樣的功能,對於r語言來說,如果要輸出多個結果,需要把這些結果聚合到乙個資料結構裡面,在返回這個資料結構。參見下面的例子:
in [33]: def ff(a,b):
...: return(a+b,a-b)
in [34]: ff(1,2)
out[34]: (3, -1)
只需要在return函式裡面寫上多個值,函式就可以輸出多個結果。
Python3 4安裝日記
環境 python3.4.0,win32 安裝過python2.7,然而謎之原因解除安裝了,其實2.7和3.4可以共存。在登錄檔和path內刪除了python2.7的記錄,然後安裝py3.4。尚未找到原因,估計是某個lib過於古老。解除安裝重新安裝python 3.4,可以使用pip 始終建議使用p...
Python3 4執行緒入門
比較成熟的程式語言,基本上都有對執行緒的支援,而python也不例外,下面散仙來看下python裡面對幾個執行緒比較的類或方法 python多執行緒程式設計,一般使用thread和threading模組。thread模組想對較底層,threading模組對thread模組進行了封裝,更便於使用。所有...
python3 4之決策樹
usr bin env python coding utf 8 import numpy as np from sklearn import tree from sklearn.metrics import precision recall curve from sklearn.metrics im...