函數(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 的值,由此確認它實際上不受 先前調用的函數中的局部變量的影響。
若是你想給一個在程序頂層的變量賦值(也就是說它不存在於任何做用域中,不管是函數還 是類),那麼你必須告訴 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 語句用於從函數中返回,也就是中斷函數。咱們也能夠選擇在中斷函數時從函數中返 回一個值
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 的內置函數已經實現了「找到最大數」這一功能,因此儘量地使 用這一內置函數。
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 模塊。
IT入門 感謝關注
練習地址:www.520mg.com/it