微信公衆號:碼農充電站pro
我的主頁:https://codeshellme.github.iohtml
測試只能證實程序有錯誤,而不能證實程序沒有錯誤。
—— Edsger Dijkstrajava
目錄python
本節咱們來介紹函數
,在前邊的章節咱們已經接觸了挺多函數了,好比print()
,len()
等。git
函數是編程語言中很是重要的概念,函數是一段可重複利用
的,提供特定功能
的代碼段。github
函數是一種模塊化
的手段,可提升代碼的利用率,避免重複代碼,便於使用,便於維護。shell
Python 中,不只提供了許多現成可用的內建函數
,用戶還能夠根據本身的需求,定義本身的函數
。編程
在Python 中,內建函數用builtin_function_or_method
表示,自定義函數用function
表示。數組
函數也屬於一種數據類型,可用type()
查看:微信
>>> type(len) # len() 是內建函數 <class 'builtin_function_or_method'> >>> >>> type(print) # print() 是內建函數 <class 'builtin_function_or_method'> >>> >>> def test(): pass # 自定義函數 test(),並無實質功能 ... >>> >>> type(test) # test() 是自定義函數 <class 'function'>
提示:
內建函數
就是Python 原生支持,自帶的函數(好比print()
),用於區分用戶自定函數
。數據結構
函數定義的格式以下:
def fun_name(參數列表...): # 函數體 ...
首先,定義函數須要用到def
關鍵字,後跟函數名
,而後是參數列表
,參數列表寫在小括號()
內,再日後是一個冒號:
,函數體
通常寫在下一行,注意要有縮進
。
例如,咱們定義一個簡單的函數:
def hello_python(): print('hello python.')
該函數值輸出一個字符串hello python.
,其中:
hello_python
爲函數名print('hello python.')
文檔字符串
咱們能夠在函數體的第一行,寫一段該函數的說明,此說明用三引號'''
或 """
引住,這被稱爲文檔字符串
。以下:
def hello_python(): '''這是函數的一段說明''' print('hello python.')
要想查看這段說明,可使用格式函數名.__doc__
來訪問,以下:
>>> hello_python.__doc__ '這是函數的一段說明'
咱們也能夠訪問內建函數的文檔字符串,好比len()
函數:
>>> len.__doc__ 'Return the number of items in a container.'
調用函數時,只須要用函數名
和參數列表
就行,好比上面的函數,調用以下:
hello_python() # 輸出 hello python.
其實,在Python 中,函數
也是一種類型,函數名
就是一個函數類型
的變量。
所以,能夠將一個函數名賦值給一個變量,以下:
abc = hello_python print(type(abc)) # 輸出 <class 'function'> abc() # 就像調用 hello_python() 同樣
定義函數時,能夠傳給函數一些數據,這些數據叫作函數參數
。
定義一個帶參數的函數,以下:
def hello(string): print('hello %s.' % string)
其中的string
就是函數參數,函數參數能夠有多個,這裏咱們只寫了一個參數。
此時,調用該函數時,就須要給函數傳遞參數了,以下:
hello('python') # 輸出 hello python. hello('java') # 輸出 hello java. hello('html') # 輸出 hello html.
若是參數傳遞出現錯誤,則會出現TypeError
異常,參數傳遞錯誤包括:
定義參數時,能夠包含默認參數
,默認參數能夠有多個。
默認參數就是,這個參數能夠傳遞,也能夠不傳遞:
以下,咱們定義了一個帶有默認參數的函數:
def sum(a, b=0, c=1): n = a + b + c print(n)
默認參數必須寫在普通參數的後邊,默認參數後邊不能再有普通參數。
其中,參數a
是普通參數,參數b
和c
都是默認參數,用賦值語句
賦予了它們默認值。
參數b
的默認值是0
,參數c
的默認值是1
。
當沒有傳遞b
時,b
爲0
,當沒有傳遞c
時,c
爲 1
。
咱們能夠這樣調用sum
函數:
sum(2) # 只傳遞了 a,b 和 c 都是默認值 sum(2, 3) # 傳遞了 a 和 b,c 是默認值 sum(2, 3, 5) # a,b,c 都傳遞了 sum(a=2, b=5) # 傳遞參數時,普通參數和默認參數均可以加上參數名 sum(2, c=7) # 傳遞了a 和 c,b 是默認值 sum(2, b=2, c=7) # 傳遞默認參數時,能夠加上參數名 sum(c=2, a=2, b=7) # 傳遞參數時,若是有參數名,參數的順序能夠隨意
須要注意的是:
默認參數不要是可變類型
默認參數能夠是任意類型的數據,可是建議不要是可變類型數據,不然容易出現不可預料的結果。
好比代碼:
def test(l=[]): l.append(1) return l
當調用該函數時,若是傳遞了參數,這種狀況下通常不會出現什麼問題:
>>> test([]) [1] >>> test([2]) [2, 1]
可是,若是沒有傳遞參數,而是使用的默認參數,結果可能不是你想象的:
>>> test() [1] >>> test() [1, 1] >>> test() [1, 1, 1]
如上代碼,咱們連續調用了三次test()
,都使用的是默認參數。
第一次調用彷佛仍是正常的,但後兩次的結果顯示,函數返回的結果,應該是累計了前邊調用。
這是由於,當使用默認參數時,函數記錄了默認參數的一開始的變量地址
,這個變量地址始終是不會改變的,可是若是這個變量類型是可變類型
的數據(好比例子中的列表類型),那麼其中的值是有可能改變的。
這就是出現以上狀況的緣由,因此,建議在使用默認參數時,不要使用可變類型的參數,容易出問題。
當你不知道函數的參數有幾個的時候,你可使用不定長參數。
不定長參數的格式,是在普通參數以前加一個星號*
,以下:
def print_num(*num): print(num)
此時,在函數內部,num
其實是一個元組
類型。因此,咱們以元組的方式來操做num
便可。
咱們能夠給該函數傳遞不一樣個數
的參數:
print_num(1) # 傳遞了 1 個參數,num = (1) print_num(1, 2) # 傳遞了 2 個參數,num = (1, 2) print_num(1, 2, 3) # 傳遞了 3 個參數,num = (1, 2, 3)
有名參數
不定長的有名參數
,是在普通參數以前加兩個星號**
,以下:、
def print_num(**num): print(num)
此時,在函數內部,num
其實是一個字典
類型。因此,咱們以字典的方式來操做num
便可。
咱們能夠給該函數傳遞不一樣個數
的有名參數
,參數名
被解析成了字符串類型:
print_num(a=1) # 傳遞了 1 個參數,num = {'a': 1} print_num(a=1, b=2) # 傳遞了 2 個參數,num = {'a': 1, 'b': 2}
各類參數的順序
若是一個函數中各類參數都有的話,它們的順序是有要求的:以下:
def 函數名(普通參數,默認參數,不定長參數,不定長有名參數): # 函數體 ...
建議:
不要使用太多的參數組合,不便於理解
因爲函數
也是一種數據類型,因此函數也能夠做爲函數參數
傳遞給函數,而後在函數內部,再調用該函數。
def sum(a, b): return a + b def test(fun): n = fun(1, 2) print(n) test(sum)
上面代碼中,sum
與 test
都是函數。
sum()
函數,計算兩個參數之和,並將結果返回。
test()
函數,接收一個參數 fun
,該參數是一個函數類型。在函數體內,用代碼n = fun(1, 2)
進行調用。
代碼test(sum)
,將函數sum
做爲參數傳遞給test()
。
以上就是函數
做爲函數參數
的用法。
函數能夠有返回值,也能夠沒有返回值。
函數的返回值,須要用到return
關鍵字,當函數的執行遇到return
時,函數的執行就會結束,而且返回一個值。
若是一個函數沒有調用return
,那麼在函數執行完畢後,會默認返回None
:
def test(): print('hello python.') # 沒有使用 return ret = test() # ret 爲 None
若是一個函數調用了return
,可是return
後邊沒有值,那麼此時的含義是,表示函數立馬返回,且返回值爲None
:
def test(): print('hello python.') return # return 後邊的語句永遠不會被執行到 print('hello java.') ret = test() # ret 爲 None
你能夠在return
後邊跟一個任意類型的值,做爲函數的返回值:
def test(flag): if flag: return True # 返回 True else: return False # 返回 False ret = test(True) # ret 爲 True ret = test(False) # ret 爲 False
函數返回多個值
函數不只能夠返回一個值,也能夠返回多個值:
def test(a, b, c): return a, b, c
實際上這個時候,a, b, c
被自動打包
到了一個元組裏邊,咱們用一個變量去接收返回值:
ret = test(1, 2, 3) print(ret) # ret 爲 (1, 2, 3) print(type(ret)) # <class 'tuple'>
咱們也能夠用三個變量去接收這個返回值,這時返回值會被自動解包
:
a, b, c = test(1, 2, 3) # a 爲 1 # b 爲 2 # c 爲 3
自動解包時,若是變量的個數與返回值的個數不一樣,會拋出ValueError
異常:
a, b = test(1, 2, 3) # 變量少於返回值,拋出異常 a, b, c, d = test(1, 2, 3) # 變量多於返回值,拋出異常
Python 中的匿名函數使用 lambda
關鍵字,也稱爲lambda
表達式。
lambda
表達式雖然也是函數
,可是通常只包含簡單的邏輯,它是普通函數的一種簡寫形式。通常常做爲函數參數,傳遞給函數。
格式以下:
lambda 參數列表 : 表達式
lambda
後跟一個參數列表,而後是一個冒號:
,最後是一個表達式,表達式的計算結果會做爲匿名函數的返回值
(不須要用return
)。
能夠將lambda
表達式賦值給一個變量,格式以下:
變量名 = lambda 參數列表 : 表達式
示例:
sum = lambda x, y : x + y
該匿名函數接收兩個參數x
,y
,而後計算結果 x + y
,並將結果返回。
經過type(sum)
查看其類型:
>>> type(sum) <class 'function'>
上面這個lambda
表達式就至關於以下函數:
def sum(x, y): return x + y
咱們能夠像調用普通函數同樣,調用該lambda
表達式:
>>> sum(1, 2) # 返回 1 + 2 3 >>> sum(2, 3) # 返回 2 + 3 5
匿名函數的應用場景
在介紹Python 列表的時候,咱們介紹過一個L.sort()
函數,該函數的原型以下:
L.sort(key=None, reverse=False) -> None
其中的key
參數就是一個函數類型參數,這種狀況下就可使用匿名函數。以下:
>>> l.sort(key = lambda x: x[0]) >>> l [('a', 3), ('b', 2), ('c', 1)] >>> >>> l.sort(key = lambda x: x[1]) >>> l [('c', 1), ('b', 2), ('a', 3)]
(完。)
推薦閱讀:
Python 簡明教程 --- 14,Python 數據結構進階
歡迎關注做者公衆號,獲取更多技術乾貨。