函式,是程式設計中很重要的一個概念。簡單來說,函式是一段可重複使用的程式碼段,給這段程式碼起個名字就是“函式名”。在程式的任何地方都可以透過函式名來使用這段程式碼,這就是“函式呼叫”。
函式的定義
函式的概念,其實我們在初中數學中就接觸過了。比如,這個表示式y = 2x + 3
,我們就稱y是x的一次函式。寫成Python函式就是這樣的:
def y(x):
return 2 * x + 3
如上例所示,Python中定義一個函式的規則是這樣的:
首先是透過關鍵字def
來確定它是一個函式,後面跟著函式名(比如上面的y
),函式名後面是小括號括起來的引數,括號外面以冒號:
結尾這一行。這一行就是函式的宣告。
接下來是函式體的程式碼片段,可以是一行也可以是多行,但它們比def
多了一個縮排。函式體最後一行可以透過關鍵字return
返回一個或多個值。如果沒有寫return
,Python預設為返回None
。
有一種特殊的函式定義:空函式,就是什麼都不做的函式,它透過一個pass
語句來定義函式體:
def do_nothing():
pass
空函式主要是在我們寫程式最開始,想好都有哪些函式要寫,先定義成空函式再慢慢實現它們具體的功能。
同樣的,後面我們學習Python物件導向程式設計時類(class)的定義也可以用pass
來實現一個最小類:
class TheEmptyClass:
pass
函式的呼叫
定義好一個函式後,我們就可以呼叫(執行)該函式了。呼叫函式就是透過函式名再傳入它需要的引數即可。
a = y(2)
print('a is ', a)
b = y(6)
print('b is ', b)
結合函式y
的定義,猜猜看a和b的值分別為多少吧。
函式y是一個數學運算的函式,它的引數應該是整數或浮點數。如果我們給它傳一個字串進去,看看會有什麼結果呢?
In [153]: y('a')
-----------------
TypeError Traceback (most recent call last)
<ipython-input-153-1e7b94eb7c3d> in <module>
----> 1 y('a')
<ipython-input-150-d8eda758862f> in y(x)
1 def y(x):
----> 2 return 2 * x + 3
3
TypeError: must be str, not int
根據函式體的語句,我們先把字串'a'
乘以2得到'aa'
,再計算'aa'
字串和整數3
的加法就會報錯,因為字串和整數是不能做加法運算的。
我們定義的函式y只有一個引數,如果我們給它傳入兩個或更多引數,同樣也會報錯。小猿們可以自己試試看引數個數不對時是什麼樣的錯誤。
因此,函式的呼叫,需要滿足函式名、引數型別、引數個數都要符合函式的定義才能執行成功。
函式的返回值
在Python中函式都是有返回值的。如果我們沒有透過return
顯示的返回,則Python預設返回None
。透過return
我們就可以規定函式返回我們想要的值。我們想要的值可能是一個,也可能是兩個或多個,return
都能滿足我們的要求。
def my_division(a, b):
quotient = a // b
remainder = a % b
return quotient, remainder
這個函式計算a除以b,返回它們的商和餘數兩個值。return
返回多個值時,用逗號,
隔開它們即可。
我們看看呼叫該函式執行的結果:
In [158]: my_division(5, 2)
Out[158]: (2, 1)
In [159]: my_division(20, 7)
Out[159]: (2, 6)
In [160]: my_division(20, 5)
Out[160]: (4, 0)
可以看到,函式返回多個值時,這多個值組成了一個tuple(元組)。
遞迴函式
遞迴函式就是函式自己呼叫自己。我們以計算一個整數的階乘來看看遞迴函式是什麼樣子的。階乘的公式如下:
n! = n * (n-1) * (n-2) * … * 2 * 1
它的遞迴函式的定義如下:
def factorial(n):
if n == 1:
print(n)
return 1
print(n, '*', end=' ')
return n * factorial(n-1)
遞迴函式都有一個跳出遞迴的條件,在本函式中就是n == 1
。當n != 1
時就遞迴呼叫求比當前n小1的數的階乘,每次n減1,知道n == 1
結束遞迴。這個遞迴過程其實就是生成了連乘(可以看函式的列印資訊):
n * (n-1) * (n-2) * … * 2 * 1
In [169]: f = factorial(5)
5 * 4 * 3 * 2 * 1
In [170]: f = factorial(10)
10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1
總結
定義函式的要素:函式名、引數、函式體
呼叫函式的注意事項:引數型別、引數個數
函式體最後沒有使用return
語句則預設返回None
函式透過return
返回一個或多個值,多個值以tuple的形式返回
練習
把上面的遞迴函式改寫成用迴圈實現的函式,思考一下遞迴和迴圈的關係。
我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。
***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***