Python 中,函數的應用非常廣泛,前面章節中我們已經接觸過多個函數,比如 input() 、print()、range()、len() 函數等等,這些都是 Python 的内置函數,可以直接使用。
除了可以直接使用的内置函數外,Python 還支援自定義函數,即将一段有規律的、可重複使用的代碼定義成函數,進而達到一次編寫、多次調用的目的。
比如,在程式中定義了一段代碼,這段代碼用于實作一個特定的功能。問題來了,如果下次需要實作同樣的功能,難道要把前面定義的代碼複制一次?如果這樣做實在太傻了,這意味着每次當程式需要實作該功能時,都要将前面定義的代碼複制一次。正确的做法是,将實作特定功能的代碼定義成一個函數,每次當程式需要實作該功能時,隻要執行(調用)該函數即可。
通俗來講,所謂函數,就是指為一段實作特定功能的代碼“取”一個名字,以後即可通過該名字來執行(調用)該函數。使用函數,可以大大提高代碼的重複使用率。
通常,函數可以接收零個或多個參數,也可以傳回零個或多個值。從函數使用者的角度來看,函數就像一個“黑匣子”,程式将零個或多個參數傳入這個“黑匣子”,該“黑匣子”經過一番計算即可傳回零個或多個值。
對于“黑匣子”的内部細節(就是函數的内部實作細節),函數的使用者并不需要關心。就像前面在調用 len()、max()、min() 等函數時,我們隻負責傳入參數、接收傳回值,至于函數内部的實作細節,我們并不關心。
如圖 1 所示為函數調用示意圖:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZucjUxAFN0EzMxIjWx0iMvw1MxIDM5EzLcdWbpxGbh9CXzRWYvxGc19CX0Vmbucmblh2YuFWai5yYvw1LcpDc0RHaiojIsJye.gif)
圖 1 函數調用示意圖
從函數定義者(實作函數的人)的角度來看,其至少需要想清楚以下 3 點:
函數需要幾個關鍵的需要動态變化的資料,這些資料應該被定義成函數的參數。
函數需要傳出幾個重要的資料(就是調用該函數的人希望得到的資料),這些資料應該被定義成傳回值。
函數的内部實作過程。
不難看出,定義函數比調用函數要難得多,而本節正是教你如何定義函數的。不過不用擔心,對于實作過程複雜的函數,定義本身就很費力,有時候實作不出來也完全正常。
Python函數的定義
定義函數,也就是建立一個函數,可以了解為建立一個具有某些用途的工具。定義函數需要用 def 關鍵字實作,具體的文法格式如下:
def 函數名(形參清單):
//由零條到多條可執行語句組成的代碼塊
[return [傳回值]]
其中,用 [] 括起來的為可選擇部分,即可以使用,也可以省略。
此格式中,各部分參數的含義如下:
函數名:從文法角度來看,函數名隻要是一個合法的辨別符即可;從程式的可讀性角度來看,函數名應該由一個或多個有意義的單詞連綴而成,每個單詞的字母全部小寫,單詞與單詞之間使用下畫線分隔。
形參清單:用于定義該函數可以接收的參數。形參清單由多個形參名組成,多個形參名之間以英文逗号(,)隔開。一旦在定義函數時指定了形參清單,調用該函數時就必須傳入相應的參數值,也就是說,誰調用函數誰負責為形參指派。
注意,在建立函數時,即使函數不需要參數,也必須保留一對空的“()”,否則 Python 解釋器将提示“invaild syntax”錯誤。另外,如果想定義一個沒有任何功能的空函數,可以使用 pass 語句作為占位符。
下面程式定義了兩個函數:
def my_max(x, y) :
# 定義一個變量z,該變量等于x、y中較大的值
z = x if x > y else y
# 傳回變量z的值
return z
# 定義一個函數,聲明一個形參
def say_hi(name) :
print("===正在執行say_hi()函數===")
return name + ",您好!"
Python函數的調用
調用函數也就是執行函數。如果把建立的函數了解為一個具有某種用途的工具,那麼調用函數就相當于使用該工具。
函數調用的基本文法格式如下所示:
函數名([形參值])
其中,函數名即指的是要調用的函數的名稱;形參值指的是當初建立函數時要求傳入的各個形參的值。需要注意的是,建立函數有多少個形參,那麼調用時就需要傳入多少個值,且順序必須和建立函數時一緻。即便該函數沒有參數,函數名後的小括号也不能省略。
例如,調用前面建立的那 2 個函數,執行代碼如下:
a = 6
b = 9
# 調用my_max()函數,将函數傳回值指派給result變量
result = my_max(a , b) # ①
print("result:", result)
# 調用say_hi()函數,直接輸出函數的傳回值
print(say_hi("孫悟空")) # ②
上面程式中,分别在 ① 号、② 号代碼處調用了 my_max() 和 say_hi() 這兩個函數。從下面的運作結果可以看出,當程式調用一個函數時,既可以把調用函數的傳回值指派給指定變量,也可以将函數的傳回值傳給另一個函數,作為另一個函數的參數。
運作上面程式,将可以看到如下運作結果:
result: 9
===正在執行say_hi()函數===
孫悟空,您好!
另外,在函數體中使用 return 語句可以顯式地傳回一個值,return 語句傳回的值既可是有值的變量,也可是一個表達式。例如上面的 my_max() 函數,實際上也可簡寫為如下形式:
def my_max(x, y) :
# 傳回一個表達式
return x if x > y else y
為函數提供說明文檔
前面介紹過可以使用 Python 内置的 help() 函數檢視其他函數的幫助文檔,我們也經常通過 help() 函數檢視指定函數的幫助資訊,這對于 Python 開發者來說非常重要。
我們還可以為函數編寫說明文檔,隻要把一段字元串放在函數聲明之後、函數體之前,這段字元串将被作為函數的部分,這個文檔就是函數的說明文檔。
程式既可通過 help() 函數檢視函數的說明文檔,也可通過函數的 __doc__ 屬性通路函數的說明文檔。下面程式示範了為函數編寫說明文檔:
def my_max(x, y) :
'''
擷取兩個數值之間較大數的函數。
my_max(x, y)
傳回x、y兩個參數之間較大的那個
'''
# 定義一個變量z,該變量等于x、y中較大的值
z = x if x > y else y
# 傳回變量z的值
return z
上面程式使用多行字元串的文法為 my_max() 函數編寫了說明文檔,接下來程式既可通過 help() 函數檢視該函數的說明文檔,也可通過 __doc__ 屬性通路該函數的說明文檔。
# 使用help()函數檢視my_max的幫助文檔
help(my_max)
#或者 print(my_max.__doc__)
運作上面代碼,可以看到如下運作結果:
Help on function my_max in module __main__:
my_max(x, y)
擷取兩個數值之間較大數的函數。
my_max(x, y)
傳回x、y兩個參數之間較大的那個。