文章目錄
- 1、定義函數:
- 2、函數形參:
- 3、局部變數:
- 4、全域變數:
- 5、外部變數:
- 6、預設參數值
- 7、關鍵字(Keyword)參數:
- 8、可變(VarArgs)參數:
- 9、關鍵字限定(Keyword-only)參數:
- 10、return語句
- 11、文檔字串(DocStrings):
六、函數:
函數是重用的程式段。它們允許你給一塊語句一個名稱,然後你可以在你的程式的任何地方使用這個名稱任意多次地運行這個語句塊。這被稱為調用函數。我們已經使用了許多內建的函數,比如len和range。
函數通過def關鍵字定義。def關鍵字後跟一個函數的標識符名稱,然後跟一對圓括弧。圓括弧之中可以包括一些變數名,該行以冒號結尾。接下來是一塊語句,它們是函數體。
1、定義函數:
例如:
# Filename: function1.py def sayHello(): print('Hello World!') # block belonging to the function# End of function sayHello() # call the functionsayHello() # call the function again
輸出:
C:\Users\Administrator>python D:\python\function1.py
Hello World!
Hello World!
工作原理:
我們使用上面解釋的文法定義了一個稱為sayHello
的函數。這個函數不使用任何參數,因此在圓括弧中沒有聲明任何變數。參數對於函數而言,只是給函數的輸入,以便於我們可以傳遞不同的值給函數,然後得到相應的結果。我們在上程式中調用了兩次相同的函數從而避免了對同一程式段寫兩次。
2、函數形參:
函數取得的參數是你提供給函數的值,這樣函數就可以利用這些值做一些事情。這些參數就像變數一樣,只不過它們的值是在我們調用函數的時候定義的,而非在函數本身內賦值。
參數在函數定義的圓括弧對內指定,用逗號分割。當我們調用函數的時候,我們以同樣的方式提供值。注意我們使用過的術語——函數中的參數名稱為形參而你提供給函數調用的值稱為實參。
使用函數形參:
例如:
# Filename: func_param.py def printMax(a, b): if a > b: print(a, 'is maximum') elif a == b: print(a, 'is equal to', b) else: print(b, 'is maximum') printMax(3, 4) # directly give literal values x = 5y = 7 printMax(x, y) # give variables as arguments
輸出:
C:\Users\Administrator>python D:\python\func_param.py
4 is maximum
7 is maximum
工作原理:
這裡,我們定義了一個稱為printMax的函數,這個函數需要兩個形參,a和b。我們使用if..else語句找出兩者之中較大的一個數,並且列印較大的那個數。
在第一個printMax使用中,我們直接把數,即實參,提供給函數。在第二個使用中,我們使用變數調用函數。printMax(x, y)使實參x的值賦給形參a,實參y的值賦給形參b。在兩次調用中,printMax函數的工作完全相同。
3、局部變數:
當你在函數定義內聲明變數的時候,它們與函數外具有相同名稱的其他變數沒有任何關係,即變數名稱對於函數來說是 局部 的。這稱為變數的範圍 。所有變數的範圍是它們被定義的塊,從它們的名稱被定義的那點開始。
例如:
# Filename: func_local.py x = 50 def func(x): print('x is', x) x = 2 print('Changed local x to', x) func(x)print('x is still', x)
輸出:
C:\Users\Administrator>python D:\python\func_local.py
x is 50
Changed local x to 2
x is still 50
工作原理:
在函數中,我們第一次使用x的 值 的時候,Python使用函式宣告的形參的值。
接下來,我們把值2賦給x。x是函數的局部變數。所以,當我們在函數內改變x的值的時候,在主塊中定義的x不受影響。
在最後一個print語句中,我們證明了主塊中的x的值確實沒有受到影響。
4、全域變數:
如果你想要為一個定義在函數外的變數賦值,那麼你就得告訴Python這個變數名不是局部的,而是全域的。我們使用global陳述式完成這一功能。沒有global語句,是不可能為定義在函數外的變數賦值的。
你可以使用定義在函數外的變數的值(假設在函數內沒有同名的變數)。然而,並不推薦這樣做,並且我們應該盡量避免這樣做,因為這使得程式的讀者會不清楚這個變數是在哪裡定義的。使用global語句可以清楚地表明變數是在外面的塊定義的。
我們可以這樣使用:
# Filename: func_global.py x = 50 def func(): global x print('x is', x) x = 2 print('Changed global x to', x) func()print('Value of x is', x)
輸出:
C:\Users\Administrator>python D:\python\func_global.py
x is 50
Changed global x to 2
Value of x is 2
工作原理:
global語句被用來聲明x是全域的——因此,當我們在函數內把值賦給x的時候,這個變化也反映在我們在主塊中使用x的值的時候。
你可以使用同一個global語句指定多個全域變數。例如global x, y, z。
5、外部變數:
上面我們已經知道如何使用局部變數和全域變數,還有一個外部變數是在以上兩種變數之間的變數。當我們在函數內聲明了外部變數則在函數中就可見了。
由於任何東西在python內都是可執行代碼,所以你可以在任何位置定義函數,就如以下例子中的func_inner()定義在func_outer()內也是可以的。
以下例子說明如何使用外部變數:
# Filename: func_nonlocal.py def func_outer(): x = 2 print('x is', x) def func_inner(): nonlocal x x = 5 func_inner() print('Changed local x to', x) func_outer()
輸出:
C:\Users\Administrator>python D:\python\func_nonlocal.py
x is 2
Changed local x to 5
工作原理:
當我們在func_inner()函數中的時候,在函數func_outer()內第一行定義的變數x既不是內部變數(它不在func_inner塊內)也不是全域變數(它也不在主程式塊內),這時我們使用nonlocal x聲明我們需要使用這個變數。
你可以嘗試改變聲明方式,然後觀察這幾種變數的區別。
6、預設參數值
對於一些函數,你可能希望它的一些參數是可選的,如果使用者不想要為這些參數提供值的話,這些參數就使用預設值。這個功能藉助於預設參數值完成。你可以在函數定義的形參名後加上賦值運算子(=)和預設值,從而給形參指定預設參數值。
注意,預設參數值應該是一個常數。更加準確的說,預設參數值應該是不可變的。
使用預設參數值:
例如:
# Filename: func_default.py def say(message, times = 1): print(message * times) say('Hello')say('World', 5)
輸出:
C:\Users\Administrator>python D:\python\func_default.py
Hello
WorldWorldWorldWorldWorld
工作原理:
名為say的函數用來列印一個字串任意所需的次數。如果我們不提供一個值,那麼預設地,字串將只被列印一遍。我們通過給形參times指定預設參數值1來實現這一功能。
在第一次使用say的時候,我們只提供一個字串,函數只列印一次字串。在第二次使用say的時候,我們提供了字串和參數5,表明我們想要列印這個字串訊息5遍。
註:
只有在形參表末尾的那些參數可以有預設參數值,即你不能在聲明函數形參的時候,先聲明有預設值的形參而後聲明沒有預設值的形參。
這是因為賦給形參的值是根據位置而賦值的。例如,def func(a, b=5)
是有效,但是def func(a=5, b)
是無效的。
7、關鍵字(Keyword)參數:
如果你的某個函數有許多參數,而你只想指定其中的一部分,那麼你可以通過命名來為這些參數賦值——這被稱作關鍵字參數,我們使用名字(關鍵字)而不是位置(我們前面所一直使用的方法)來給函數指定實參。
這樣做有兩個優勢:一,由於我們不必擔心參數的順序,使用函數變得更加簡單了;二、假設其他參數都有預設值,我們可以只給我們想要的那些參數賦值。
使用關鍵參數:
# Filename: func_key.py def func(a, b=5, c=10): print('a is', a, 'and b is', b, 'and c is', c) func(3, 7)func(25, c=24)func(c=50, a=100)
輸出:
C:\Users\Administrator>python D:\python\func_key.py
a is 3 and b is 7 and c is 10
a is 25 and b is 5 and c is 24
a is 100 and b is 5 and c is 50
工作原理:
名為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的值。
8、可變(VarArgs)參數:
有些時候你可能希望定義一個可以接受任意個數參數的函數,你可以使用星號來完成。
例如:
# Filename: total.py def total(initial=5, *numbers, **keywords): count = initial for number in numbers: count += number for key in keywords: count += keywords[key] return count print(total(10, 1, 2, 3, vegetables=50, fruits=100))
輸出:
C:\Users\Administrator>python D:\python\total.py
166
工作原理:
當我們以星號聲明一個形參,如*param,從這個位置開始到結束的實參都將被收集在'param'元組內,類似的,當我們以雙星號聲明一個形參,例如**param,則從這個位置開始到結束的實參都將會被收集在一個叫'param'的字典中。
對於元組和字典,我們後面有詳細講解。
9、關鍵字限定(Keyword-only)參數:
如果我們希望某些關鍵形參只能通過關鍵字實參的到而不是通過位置得到,我們可以將其聲明在星號參數後面。
例如:
# Filename: keyword_only.py def total(initial=5, *numbers, extra_number): count = initial for number in numbers: count += number count += extra_number print(count) total(10, 1, 2, 3, extra_number=50)total(10, 1, 2, 3)# Raises error because we have not supplied a default argument value for 'extra_number'
輸出:
C:\Users\Administrator>python D:\python\keyword_only.py
66
Traceback (most recent call last):
File "D:\python\keyword_only.py", line 11, in <module>
total(10, 1, 2, 3)
TypeError: total() needs keyword-only argument extra_number
工作原理:
在星號形參後聲明的形成就成了關鍵字限定參數。如果沒有為這些實參提供一個預設值,那麼必須在調用函數時以關鍵字實參為其賦值,否則將引發錯誤,如上例所示。
注意這裡用到的x+=y等同於x=x+y。如果你不需要星號形參只需要關鍵字限定形參則可以省略星號形參的參數名,如total(initial=5, *, extra_number)。
10、return語句
return語句用來從一個函數返回即跳出函數。我們也可選從函數返回一個值。
例如:
# Filename: func_return.py def maximum(x, y): if x > y: return x elif x == y: return 'The numbers are equal' else: return y print(maximum(2, 3))
輸出:
C:\Users\Administrator>python D:\python\func_return.py
3
工作原理:
maximum函數返回參數中的最大值,在這裡是提供給函數的數。它使用簡單的if..else語句來找出較大的值,然後返回那個值。
注意,沒有傳回值的return語句等價於return None。None是Python中表示沒有任何東西的特殊類型。例如,如果一個變數的值為None,可以表示它沒有值。
除非你提供你自己的return語句,每個函數都在結尾暗含有return None語句。通過運行print someFunction(),你可以明白這一點,函數someFunction沒有使用return語句,如同:
def someFunction(): passprint(someFunction())
輸出就是None。
提示:python已經包含了一個被稱作max的內建函數,它的功能即是尋找最大值,你可以儘可能使用這個函數。
11、文檔字串(DocStrings):
Python有一個很奇妙的特性,稱為文檔字串,它通常被簡稱為docstrings。DocStrings是一個重要的工具,由於它協助你的程式文檔更加簡單易懂。你甚至可以在程式啟動並執行時候,從函數恢複文檔字串!
例如:
# Filename: func_doc.py def printMax(x, y): '''Prints the maximum of two numbers. The two values must be integers.''' x = int(x) # convert to integers, if possible y = int(y) if x > y: print(x, 'is maximum') else: print(y, 'is maximum') printMax(3, 5)print(printMax.__doc__)
輸出:
C:\Users\Administrator>python D:\python\func_doc.py
5 is maximum
Prints the maximum of two numbers. The two values must be integers.
工作原理:
在函數的第一個邏輯行的字串是這個函數的文檔字串。同時,DocStrings也適用於模組和類,我們會在後面相應的章節學習它們。
文檔字串的慣例是一個多行字串,它的首行以大寫字母開始,句號結尾。第二行是空行,從第三行開始是詳細的描述。 強烈建議在函數中使用文檔字串時遵循這個慣例。
你可以使用__doc__(注意雙底線)調用printMax函數的文檔字串屬性(屬於函數的名稱)。Python把每一樣東西都作為對象,包括這個函數。
如果你已經在Python中使用過help(),那麼你已經看到過DocStings的使用了!它所做的只是抓取函數的__doc__屬性,然後整潔地展示給你。你可以對上面這個函數嘗試一下——只是在你的程式中包括help(printMax)。記住按q退出help。
自動化工具也可以以同樣的方式從你的程式中提取文檔。因此,我們強烈建議你對你所寫的任何正式函數編寫文檔字串。隨你的Python發行版附帶的pydoc命令,與help()類似地使用DocStrings。