一、概述
在編寫腳本的過程中,對於要重複完成的工作,我們可以提取出來,將其編寫爲函數,在腳本中使用時,調用即可,在python中,函數必須先聲明,然後才能在腳本中使用。使用函數時,只要按照函數定義形式向函數傳遞必須的參數,就可以調用函數完成所需的功能。
二、自定義函數
2.1 函數聲明、調用
在python中使用def可以聲明一個函數。完整的函數是由函數名、參數以及函數實現語句組成的,在函數中也用縮進來表示語句屬於函數體。
如果函數有返回值,那麼需要在函數中使用return語句返回計算結果,聲明函數形式一般如下:
de f<函數名> (參數列表):
<函數語句>
return <返回值>
# 其中參數和返回值不是必須的
簡單示例
代碼:
def hi (): #定義一個hi()函數,這裏沒有參數,但是需要寫一對圓括號。
print('hello,word !')
hi() #調用函數
print(hi) # 返回函數在內存中的地址
執行結果:
hello,word !
<function hi at 0x0390F7C8>
以下是一個完整的函數,實現了求一個列表所有整數之和的功能,其中L爲所要求和的列表,result是列表中所有整數的和,最後使用return將result的值返回。
代碼:
def ListSum(L):
result = 0
for i in L:
result = result + i
return result
List = [ 1, 2, 3,4 ]
Sum = ListSum( List )
print( Sum )
執行結果:
10
Python的函數比較靈活。與C語言中函數的聲明相比,在Python中聲明一個函數時,不需要聲明函數類型,也不需要聲明參數的類型。Python 在實際調用函數的過程中也非常靈活,不需要爲不同類型的參數聲明多個函數,或在處理不同類型數據的時候調用相應的函數。大部分情況下都可以用同一個函數調用不同的數據類型。
如下所示的函數,其功能是打印參數對象中的所有成員:
代碼:
def PrintAll(x):
for i in x:
print(i)
l = [1, 2, 3, 4] # 列表
PrintAll(l)
t = ('a', 'b', 'c') # 元組
PrintAll(t)
d = {'tom': 1, 'anni': 2, 'susi': 3 } # 字典
PrintAll(d)
執行結果:
1
2
3
4
a
b
c
tom
anni
susi
2.2 參數讓函數更有價值
2.2.1 有默認值的參數
在python中,可以在聲明函數的時候,預先爲參數設置一個默認值。當調用函數時,如果某個參數具有默認值,則可以不向這個函數傳遞參數,這時,函數將使用事先聲明默認的參數值。
def <函數名> (參數 = 默認值):
<語句>
以下代碼聲明瞭一個函數,用來計算參數的立方值,默認參數爲5
代碼:
def Cube ( x = 5 ):
return x ** 3
print(Cube()) # 爲傳遞參數
print(Cube(2)) # 參數爲2
執行結果:
125
8
如果一個函數有多個參數,均聲明的默認值,在傳遞參數時僅想向最後一個傳遞。
代碼:
def Cube ( x = 1, y = 2, c = 3 ):
return x * y +c
print(Cube()) # 結果爲5
print(Cube(2)) # 結果爲7,傳遞的是第一個參數
print(Cube(2,3)) #結果爲9傳遞的第一二個參數
print(Cube( , , 5)) #這樣執行結果是錯的
這裏我們要換一種函數定義的方式
代碼:
def Cube ( x , y , c ):
if x == None:
x = 1
if y == None:
y = 2
if c == None:
c = 3
return x * y + c
print(Cube(None,None ,4)) # 加入判斷
執行結果:
6
2.2.2 參數傳遞方式
在Python中,參數值的傳遞不只是按照聲明函數時參數的順序進行傳遞的,實際上,Python還提供了另外一種傳遞參數的方法一按照參 數名傳遞值。以參數名傳遞參數時類似於設置參數的默認值。
使用按參數名傳遞參數的方式調用函數時,要在調用函數名後的圓括號裏爲函數的所有參數賦值,賦值的順序不必按照函數聲明時的參數順序,
代碼:
def Cube ( x , y , c ):
if x == None:
x = 1
if y == None:
y = 2
if c == None:
c = 3
return x * y + c
print(Cube(y=3,c=3,x=3)) #賦值實現
執行結果:
12
在python中也可以同時使用按參數順序傳遞與按參數名傳遞兩種方式,但是需要注意的是,按順序傳遞參數,要位於按參數名傳遞參數之前,而且不能有重複的情況,否則發生錯誤。
在有默認參數值的情況下,使用按參數名傳遞參數十分方便,上面的例子,我們就可以直接用參數名傳遞。
代碼:
def Cube ( x = 1, y = 2, c = 3 ):
return x * y + c
print (Cube(c=5) ) # 這裏x與y使用默認值,c重新被傳值
執行結果:
7
2.2.3 傳遞任意數量的值
在Python中,函數可以具有任意個參數,而不必在聲明函數時對所有參數進行定義。使用可變長參數的函數時,其所有參數都保存在一個元組裏, 在函數中可以使用for循環來處理。聲明函數時,如果在參數名前加上一個星號“*",則表示該參數是一個可變長參數
代碼:
def mylistappend(*list):
l = []
for i in list:
l.extend(i)
return l
a = [ 1, 2, 3]
b = [ 4, 5, 6]
c = [ 7, 8, 9]
x = mylistappend(a)
y = mylistappend(a,b)
z = mylistappend(a,b,c)
print(x)
print(y)
print(z)
執行結果:
[1, 2, 3]
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
2.2.4 用參數返回計算結果
在C語言中,可以通過在參數中使用指針來達到改變參數值的作用,從而/達到從函數中返回結果的目的。其實,在Python中,還有更簡單的實現方法,即在參數中使用可變對象(如列表等),使函數中的結果返回到參數中,從而達到從函數中返回計算結果的目的```
代碼:
def ChangeValue1(x):
x = x + 1
def ChangeValue2(x):
x[0] = x[0] + 2
a = 1
b = [2]
c = ChangeValue1(a)
d = ChangeValue2(b)
for i in (a,b,c,d):
print(i)
執行結果:
1 # a的值爲改變,因爲a爲不可變對象
[4] # b的值被改變
None # 函數未設返回值,所以爲空。
None
三、變量的作用域
在python中,不同的函數可以具有相同的參數名,在函數中已經聲明過的函數名,在函數之外也可以使用,而在腳本運行過程中其值並不影響。
代碼:
def fun1(x):
a = [1] # 在函數內定義一個名爲a的列表
a.append(x)
print(a)
a = [1,2,3,4] # 在函數外定義一個名爲a的列表
fun1(2)
print(a)
執行結果:
[1, 2]
[1, 2, 3, 4]
- 上述代碼中,兩個同名的列表之所以值不同,是因爲它們處於不同的作用域裏。在Python中,作用域可以分爲內置作用域、全局作用域和局部作用域。內置作用域是Python預先定義的,全局作用域是所編寫的整個腳本,局部作用域是某個函數內部範圍。
- 上述代碼中,函數中的列表a處於局部作用域中。而函數外的列表a處於全局作用域內。局部作用域內變量的改變並不影響全局作用域內的變量,除非通過引用的形式傳遞參數。
如果要在函數中使用函數外的變量,則可以在變量名前使用global關鍵字。
代碼:
def fun (x):
global a
return a + x
a = 5 # a爲全局變量,在fun函數中聲明的
print( fun(3) )
a = 2
print( fun(3) )
執行結果:
8 # 5+3
5 # 2+3
四、用lambda聲明函數
用lambda表達式來聲明函數,是Python中一類比較特殊的聲明函數的方式,lambda來源於LISP語言。使用lambda可以聲明一個匿名函數。所謂匿名函數是指所聲明的函數沒有函數名,lambda表達式就是一個簡單的函數。使用lambda聲明的函數可以返回一個值,在調用函數時,直接使用lambda表達式的返回值。使用lambda聲明函數的一般形式如下。
lambda 參數列表:表達式
以下函數定義了一個lambda函數,並調用了這個函數.
代碼:
fun = lambda x: x * x - x # 使用lambda定義一個函數,並返回函數地址
print( fun(3) ) # 返回函數值
print(fun) # 返回函數地址,fun實際指向了lambda定義的函數地址
執行結果:
6
<function <lambda> at 0x0067F7C8>
lambda適合定義小型函數,與def函數定義不同,使用lambda聲明的函數,在函數中僅能包含單一的函數參數表達式,而不能包含其他語句,在lambda中也可以調用其他的函數