07-Python函數詳解

函數(Function)是指可重複使用的程序片斷。它們容許你爲某個代碼塊賦予名字,容許你 經過這一特殊的名字在你的程序任何地方來運行代碼塊,並可重複任何次數。這就是所謂的 調用函數。python

咱們已經使用過了許多內置的函數,例如 len 和 range 。閉包

函數能夠經過關鍵字 def 來定義。這一關鍵字後跟一個函數的標識符名稱,再跟一對圓括 號,其中能夠包括一些變量的名稱,再以冒號結尾,結束這一行。函數

隨後而來的語句塊是函數 的一部分。下面的案例將會展現出這其實很是簡單:工具

def say_hello(): 
# 該塊屬於這一函數 
    print('hello world') 
# 函數結束
say_hello() # 調用函數 
say_hello() # 再次調用函數

輸出:spa

hello world

它是如何工做的code

咱們以上文解釋過的方式定義名爲 say_hello 的函數。這個函數不使用參數,所以在括號中 沒有聲明變量。函數的參數只是輸入到函數之中,以便我能夠傳遞不一樣的值給它,並得到相 應的結果。對象

要注意到咱們能夠兩次調用相同的函數,這意味着咱們沒必要從新把代碼再寫一次。作用域

函數參數

函數中的參數經過將其放置在用以定義函數的一對圓括號中指定,並經過逗號予以分隔。當 咱們調用函數時,咱們以一樣的形式提供須要的值。要注意在此使用的術語——在定義函數 時給定的名稱稱做「形參」(Parameters),在調用函數時你所提供給函數的值稱做「實 參」(Arguments)。文檔

def print_max(a, b): 
    if a > b: 
            print(a, '是比較大的數') 
    elif a == b: 
            print(a, '等於', b) 
    else:
            print(b, '是比較大的數')
# 直接傳遞字面值 
print_max(3, 4)
x = 5 
y = 7

輸出字符串

4 是比較大的數

它是如何工做的

在這裏,咱們將函數命名爲 print_max 並使用兩個參數分別稱做 a 和 b 。咱們使用一個 簡單的 if...else 語句來找出更大的那個數,並將它打印出來。

第一次調用函數 print_max 時,咱們以實參的形式直接向函數提供這一數字。

在第二次調用 時,咱們將變量做爲實參來調用函數。print_max(x, y) 將使得實參 x 的值將被賦值給形參 a ,而實參 y 的值將被賦值給形參 b 。在兩次調用中, print_max 都以相同的方式工 做。

局部變量

當你在一個函數的定義中聲明變量時,它們不會以任何方式與身處函數以外但具備相同名稱 的變量產生關係,也就是說,這些變量名只存在於函數這一局部(Local)。

這被稱爲變量的 做用域(Scope)。

全部變量的做用域是它們被定義的塊,從定義它們的名字的定義點開始。

案例:

x = 50 
def func(x): 
    print('x 是:', x) 
    x = 2 
    print('改變局部變量x爲', x)

輸出:

x 爲:50

它是如何工做的

當咱們第一次打印出存在於函數塊的第一行的名爲 x 的值時,Python 使用的是在函數聲明 之上的主代碼塊中聲明的這一參數的值。

接着,咱們將值 2 賦值給 x 。x 是咱們這一函數的局部變量。所以,當咱們改變函數中 x 的值的時候,主代碼塊中的 x 則不會受到影響。

隨着最後一句 print 語句,咱們展現出主代碼塊中定義的 x 的值,由此確認它實際上不受 先前調用的函數中的局部變量的影響。

global 語句

若是你想給一個在程序頂層的變量賦值(也就是說它不存在於任何做用域中,不管是函數還 是類),那麼你必須告訴 Python 這一變量並不是局部的,而是全局(Global)的。

咱們須要通 過 global 語句來完成這件事。由於在不使用 global 語句的狀況下,不可能爲一個定義於 函數以外的變量賦值。

你可使用定義於函數以外的變量的值(假設函數中沒有具備相同名字的變量)。然而,這 種方式不會受到鼓勵並且應該避免,由於它對於程序的讀者來講是含糊不清的,沒法弄清楚 變量的定義究竟在哪。

而經過使用 global 語句即可清楚看出這一變量是在最外邊的代碼塊 中定義的。

案例:

x = 50
def func():
global x
    print('x 爲:', x)
    x = 2
    print('改變全局變量爲', x)
func()
print('x的值爲', x)

輸出:

x 爲: 50

它是如何工做的

global 語句用以聲明 x 是一個全局變量——所以,當咱們在函數中爲 x 進行賦值時,這 一改動將影響到咱們在主代碼塊中使用的 x 的值。

你能夠在同一句 global 語句中指定不止一個的全局變量,例如 global x, y, z 。

默認參數值

對於一些函數來講,你可能爲但願使一些參數可選並使用默認的值,以免用戶不想爲他們 提供值的狀況。默認參數值能夠有效幫助解決這一狀況。

你能夠經過在函數定義時附加一個 賦值運算符( = )來爲參數指定默認參數值。

案例

def say(message, times=1):
    print(message * times)
say('Hello')
say('World', 5)

輸出

Hello

它是如何工做的

名爲 say 的函數用以按照給定的次數打印一串字符串。若是咱們沒有提供一個數值,則將按 照默認設置,只打印一次字符串。咱們經過爲參數 times 指定默認參數值 1 來實現這一 點。

在第一次使用 say 時,咱們只提供字符串於是函數只會將這個字符串打印一次。在第二次使 用 say 時,咱們既提供了字符串,同時也提供了一個參數 5 ,聲明咱們但願說(Say)這 個字符串五次。

注意

只有那些位於參數列表末尾的參數才能被賦予默認參數值,意即在函數的參數列表中擁 有默認參數值的參數不能位於沒有默認參數值的參數以前。

這是由於值是按參數所處的位置依次分配的。舉例來講, def func(a, b=5) 是有效的, 但 def func(a=5, b) 是無效的。

關鍵字參數

若是你有一些具備許多參數的函數,而你又但願只對其中的一些進行指定,那麼你能夠經過 命名它們來給這些參數賦值——這就是關鍵字參數(Keyword Arguments)——咱們使用命 名(關鍵字)而非位置(一直以來咱們所使用的方式)來指定函數中的參數

這樣作有兩大優勢

其一,咱們再也不須要考慮參數的順序,函數的使用將更加容易。

其 二,咱們能夠只對那些咱們但願賦予的參數以賦值,只要其它的參數都具備默認參數值。

案例

def func(a, b=5, c=10):
    print('a 是:', a, ' b 是:', b, ' c是:', c)
​
​
func(3, 7)
func(25, c=24)
func(c=50, a=100)

輸出

a 是: 3  b 是: 7  c是:10

它是如何工做的

名爲 func 的函數有一個沒有默認參數值的參數,後跟兩個各自帶有默認參數值的參數。

在第一次調用函數時, func(3, 7) ,參數 a 得到了值 3 ,參數 b 得到了值 7 ,而 c 得到了默認參數值 10 。

在第二次調用函數時, func(25, c=24) ,因爲其所處的位置,變量 a 首先得到了值 25。然 後,因爲命名——即關鍵字參數——指定,變量 c 得到了值 24 。變量 b 得到默認參數值 5 。

在第三次調用函數時, func(c=50, a=100) ,咱們所有使用關鍵字參數來指定值。在這裏要注 意到,儘管 a 在 c 以前定義,但咱們仍是咱們在變量 a 以前指定了變量 c 。

可變參數

有時你可能想定義的函數裏面可以有任意數量的變量,也就是參數數量是可變的,這能夠通 過使用星號來實現

案例

def total(a=5, *numbers, **phonebook):
    print('a', a)
​
    #遍歷元組中的全部項目
    for num in numbers:
        print('num項爲:', num)
​
    #遍歷字典中的全部項目
    for key, val in phonebook.items():
        print(key,val)
​
print(total(10,1,2,3,Jack=1123,John=2231,Inge=1560))

輸出

a 10

它是如何工做的

當咱們聲明一個諸如 *param 的星號參數時,今後處開始直到結束的全部位置參數 都將被收集並聚集成一個稱爲「param」的元組(Tuple)。

相似地,當咱們聲明一個諸如 **param 的雙星號參數時,今後處開始直至結束的全部關鍵字 參數都將被收集並聚集成一個名爲 param 的字典(Dictionary)。

return 語句

return 語句用於從函數中返回,也就是中斷函數。咱們也能夠選擇在中斷函數時從函數中返 回一個值

def maximum(x, y):
    if x > y:
        return x
    elif x == y:
        return '兩個數相等'
    else:
        return y
print(maximum(2, 3))

輸出:

3

它是如何工做的

maximum 函數將會返回參數中的最大值,在本例中是提供給函數的數值。它使用一套簡單的 if...else 語句來找到較大的那個值並將其返回。

要注意到若是 return 語句沒有搭配任何一個值則表明着 返回 None 。None 在 Python 中一 個特殊的類型,表明着虛無。舉個例子, 它用於指示一個變量沒有值,若是有值則它的值便 是 None(虛無) 。

每個函數都在其末尾隱含了一句 return None ,除非你寫了你本身的 return 語句。你可 以運行 print(some_function()) ,其中 some_function 函數不使用 return 語句,就像這 樣:

def some_function(): 
    pass

Python 中的 pass 語句用於指示一個沒有內容的語句塊。

提示:

有一個名爲 max 的內置函數已經實現了「找到最大數」這一功能,因此儘量地使 用這一內置函數。

DocStrings 文檔字符串

Python 有一個甚是優美的功能稱做文檔字符串(Documentation Strings),在稱呼它時一般 會使用另外一個短一些的名字docstrings。

DocStrings 是一款你應當使用的重要工具,它可以幫 助你更好地記錄程序並讓其更加易於理解。使人驚歎的是,當程序實際運行時,咱們甚至可 以經過一個函數來獲取文檔!

案例

def print_max(x, y):
    '''打印兩個數值中的最大數。
這兩個數都應該是整數'''
​
    # 若是可能,將其轉換至整數類型
    x = int(x)
    y = int(y)
    if x > y:
        print(x, '大些')
    else:
        print(y, '大些')
print_max(3, 5)
print(print_max.__doc__)

輸出

5 大些

它是如何工做的

函數的第一行邏輯行中的字符串是該函數的 文檔字符串(DocString)。這裏要注意文檔字符 串也適用於後面相關章節將提到的模塊(Modules)與類(Class)

該文檔字符串所約定的是一串多行字符串,其中第一行以某一大寫字母開始,以句號結束。第二行爲空行,後跟的第三行開始是任何詳細的解釋說明。

在此強烈建議你在你全部重要功 能的全部文檔字符串中都遵循這一約定。

咱們能夠經過使用函數的 doc (注意其中的雙下劃綫)屬性(屬於函數的名稱)來獲取 函數 print_max 的文檔字符串屬性。只消記住 Python 將全部東西都視爲一個對象,這其中 天然包括函數。咱們將在後面的類(Class)章節討論有關對象的更多細節。

自動化工具能夠以這種方式檢索你的程序中的文檔。所以,我強烈推薦你爲你編寫的全部重 要的函數配以文檔字符串。你的 Python 發行版中附帶的 pydoc 命令與 help() 使用文檔字 符串的方式相似。

嵌套函數

python容許建立嵌套函數。也就是說咱們能夠在函數裏面定義函數,並且現有的做用域和變量生存週期依舊不變。

須要注意:1.外部函數的變量能夠被內部函數所使用,但不能被內部函數修改,若要修改須要添加關鍵字nonlocal

def max(a,b):
    return a if a>b else b
print(max(5,2)) #5
def the_max(x,y,z):
    c = max(x,y)
    return max(c,z)
​
print(the_max(1,5,3))   #5

輸出

5

嵌套函數做用:

1.封裝-數據隱藏:外部沒法訪問「嵌套函數」,

2.減小重複代碼

3.閉包

閉包

啥是閉包?

若是一個函數定義在另外一個函數的做用域內,而且引用了外層函數的變量,則該函數稱爲閉包。

閉包是Python所支持的一種特性,它讓在非global scope定義的函數能夠引用其外圍空間中的變量,這些外圍空間中被引用的變量叫作這個函數的環境變量。

環境變量和這個非全局函數一塊兒構成了閉包。

def outer():
    a = 1
    def inner():
        print(a)
    return inner
inn = outer()
inn()   #1

閉包特色:

一個函數返回的函數對象,這個函數對象執行的話依賴非函數內部的變量值,這個時候,函數返回的實際內容以下:
1 函數對象
2 函數對象須要使用的外部變量和變量值

在函數的外部使用內部函數

總結

咱們已經瞭解了許多方面的函數,但咱們依舊還未覆蓋到全部類型的函數。不過,咱們已經 覆蓋到了大部分你天天平常使用都會使用到的 Python 函數。

接下來,咱們將瞭解如何建立並使用 Python 模塊。

image

IT入門 感謝關注

練習地址:www.520mg.com/it

相關文章
相關標籤/搜索