Python 簡明教程 --- 15,Python 函數

微信公衆號:碼農充電站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()),用於區分用戶自定函數數據結構

1,函數的定義

函數定義的格式以下:

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.'

2,調用函數

調用函數時,只須要用函數名參數列表就行,好比上面的函數,調用以下:

hello_python()  # 輸出 hello python.

其實,在Python 中,函數也是一種類型,函數名就是一個函數類型的變量。

所以,能夠將一個函數名賦值給一個變量,以下:

abc = hello_python
print(type(abc))      # 輸出 <class 'function'>
abc()                 # 就像調用 hello_python() 同樣

3,函數參數

定義函數時,能夠傳給函數一些數據,這些數據叫作函數參數

定義一個帶參數的函數,以下:

def hello(string):
    print('hello %s.' % string)

其中的string 就是函數參數,函數參數能夠有多個,這裏咱們只寫了一個參數。

此時,調用該函數時,就須要給函數傳遞參數了,以下:

hello('python')  # 輸出 hello python.
hello('java')    # 輸出 hello java.
hello('html')    # 輸出 hello html.

若是參數傳遞出現錯誤,則會出現TypeError 異常,參數傳遞錯誤包括:

  • 參數個數不對
  • 參數類型不適用

4,默認參數

定義參數時,能夠包含默認參數,默認參數能夠有多個。

默認參數就是,這個參數能夠傳遞,也能夠不傳遞:

  • 傳遞時,該參數就是你傳遞的值
  • 不傳遞時,該參數有默認值

以下,咱們定義了一個帶有默認參數的函數:

def sum(a, b=0, c=1):
    n = a + b + c
    print(n)

默認參數必須寫在普通參數的後邊,默認參數後邊不能再有普通參數。

其中,參數a 是普通參數,參數bc都是默認參數,用賦值語句 賦予了它們默認值。

參數b的默認值是0,參數c 的默認值是1

當沒有傳遞b 時,b0,當沒有傳遞c 時,c1

咱們能夠這樣調用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(),都使用的是默認參數。

第一次調用彷佛仍是正常的,但後兩次的結果顯示,函數返回的結果,應該是累計了前邊調用。

這是由於,當使用默認參數時,函數記錄了默認參數的一開始的變量地址,這個變量地址始終是不會改變的,可是若是這個變量類型是可變類型的數據(好比例子中的列表類型),那麼其中的值是有可能改變的。

這就是出現以上狀況的緣由,因此,建議在使用默認參數時,不要使用可變類型的參數,容易出問題。

5,不定長參數

當你不知道函數的參數有幾個的時候,你可使用不定長參數。

不定長參數的格式,是在普通參數以前加一個星號*,以下:

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 函數名(普通參數,默認參數,不定長參數,不定長有名參數):
    # 函數體
    ...

建議:

不要使用太多的參數組合,不便於理解

6,函數做爲參數

因爲函數 也是一種數據類型,因此函數也能夠做爲函數參數傳遞給函數,而後在函數內部,再調用該函數。

def sum(a, b): 
    return a + b 

def test(fun):
    n = fun(1, 2)
    print(n)

test(sum)

上面代碼中,sumtest 都是函數。

sum() 函數,計算兩個參數之和,並將結果返回。

test() 函數,接收一個參數 fun,該參數是一個函數類型。在函數體內,用代碼n = fun(1, 2) 進行調用。

代碼test(sum),將函數sum 做爲參數傳遞給test()

以上就是函數做爲函數參數的用法。

7,函數返回值

函數能夠有返回值,也能夠沒有返回值。

函數的返回值,須要用到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)  # 變量多於返回值,拋出異常

8,匿名函數

Python 中的匿名函數使用 lambda 關鍵字,也稱爲lambda 表達式。

lambda 表達式雖然也是函數,可是通常只包含簡單的邏輯,它是普通函數的一種簡寫形式。通常常做爲函數參數,傳遞給函數。

格式以下:

lambda 參數列表 : 表達式

lambda 後跟一個參數列表,而後是一個冒號:,最後是一個表達式,表達式的計算結果會做爲匿名函數的返回值(不須要用return)。

能夠將lambda 表達式賦值給一個變量,格式以下:

變量名 = lambda 參數列表 : 表達式

示例:

sum = lambda x, y : x + y

該匿名函數接收兩個參數xy,而後計算結果 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 簡明教程 --- 10,Python 列表

Python 簡明教程 --- 11,Python 元組

Python 簡明教程 --- 12,Python 字典

Python 簡明教程 --- 13,Python 集合

Python 簡明教程 --- 14,Python 數據結構進階


歡迎關注做者公衆號,獲取更多技術乾貨。

碼農充電站pro

相關文章
相關標籤/搜索