版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
循序漸進學Python之函數(shù)入門〔1〕函數(shù)是Python編程的核心內(nèi)容之一,本文首先為讀者介紹什么是函數(shù),然后詳細介紹函數(shù)的定義和調用方法,最后,我們通過大量實例代碼詳細介紹了變量的作用域以及與此有關的global語句。函數(shù)是Python編程的核心內(nèi)容之一,本文首先為讀者介紹什么是函數(shù),然后詳細介紹函數(shù)的定義和調用方法,最后,我們通過大量實例代碼詳細介紹了變量的作用域以及與此有關的global語句。一、什么是函數(shù)很多時候,Python程序中的語句都會組織成函數(shù)的形式。通俗地說,函數(shù)就是完成特定功能的一個語句組,這組語句可以作為一個單位使用,并且給它取一個名字,這樣,我們就可以通過函數(shù)名在程序的不同地方屢次執(zhí)行〔這通常叫做函數(shù)調用〕,卻不需要在所有地方都重復編寫這些語句。另外,每次使用函數(shù)時可以提供不同的參數(shù)作為輸入,以便對不同的數(shù)據(jù)進行處理;函數(shù)處理后,還可以將相應的結果反應給我們。有些函數(shù)是用戶自己編寫的,通常我們稱之為自定義函數(shù);此外,系統(tǒng)也自帶了一些函數(shù),還有一些第三方編寫的函數(shù),如其他程序員編寫的一些函數(shù),我們稱為預定義的Python函數(shù),對于這些現(xiàn)成的函數(shù)用戶可以直接拿來使用。二、為什么使用函數(shù)我們之所以使用函數(shù),主要是出于兩個方面的考慮:一是為了降低編程的難度,通常將一個復雜的大問題分解成一系列更簡單的小問題,然后將小問題繼續(xù)劃分成更小的問題,當問題細化為足夠簡單時,我們就可以分而治之。這時,我們可以使用函數(shù)來處理特定的問題,各個小問題解決了,大問題也就迎刃而解了。二是代碼重用。我們定義的函數(shù)可以在一個程序的多個位置使用,也可以用于多個程序。此外,我們還可以把函數(shù)放到一個模塊中供其他程序員使用,同時,我們也可以使用其他程序員定義的函數(shù)。這就防止了重復勞動,提供了工作效率。三、函數(shù)的定義和調用當我們自己定義一個函數(shù)時,通常使用def語句,其語法形式如下所示:def函數(shù)名〔參數(shù)列表〕:函數(shù)體其中,函數(shù)名可以是任何有效的Python標識符;參數(shù)列表是調用該函數(shù)時傳遞給它的值,可以由多個、一個或零個參數(shù)組成,當有多個參數(shù)時各個參數(shù)由逗號分隔;圓括號是必不可少的,即使沒有參數(shù)也不能沒有它;函數(shù)體是函數(shù)每次被調用時執(zhí)行的代碼,可以由一個語句或多個語句組成,函數(shù)體一定要注意縮進。此外,初學者經(jīng)常忘記圓括號后面的冒號,這會導致語法錯誤。這里介紹一下形式參數(shù)和實際參數(shù),在定義函數(shù)時函數(shù)名后面圓括號中的變量名稱叫做“形式參數(shù)〞,或簡稱為“形參〞;在調用函數(shù)時,函數(shù)名后面圓括號中的變量名稱叫做“實際參數(shù)〞,或簡稱為“實參〞。請看下面的函數(shù)定義,這里定義的函數(shù)將傳給它的數(shù)值增1,然后將增加后的值返回給調用者:defadd1(x):x=x+1returnx其中,return語句的作用是結束函數(shù)調用,并將結果返回給調用者。不過,對于函數(shù)來說,該語句是可選的,并且可以出現(xiàn)在函數(shù)體的任意位置;如果沒有return語句,那么該函數(shù)就在函數(shù)體結束位置將控制權返回給調用方,這時相當于其他編程語言中的“過程〞。在本例中,return語句是將變量x的值傳遞給調用者。我們在交互方式下測試該函數(shù),如以下圖所示:
圖1函數(shù)舉例循序漸進學Python之函數(shù)入門〔2〕函數(shù)是Python編程的核心內(nèi)容之一,本文首先為讀者介紹什么是函數(shù),然后詳細介紹函數(shù)的定義和調用方法,最后,我們通過大量實例代碼詳細介紹了變量的作用域以及與此有關的global語句。調用函數(shù)的一般形式是:
函數(shù)名〔參數(shù)表〕在圖1中,我們通過add1〔1〕來調用函數(shù)add1〔〕。其中,整數(shù)1作為參數(shù)傳遞給該函數(shù),函數(shù)將整數(shù)1加1,并將得到的結果返回給我們,所以Python解釋器顯示的數(shù)字為2。對于沒有使用return語句的函數(shù),它實際上也向調用者返回一個值,那就是None,如下所示:
圖2
無return語句的函數(shù)的“返回值〞注意,上面的函數(shù)調用方式是一種標準調用方式,傳遞的值按照形參定義的順序相應地賦給它們。除此之外,還有一種稱為“關鍵字調用〞方式,即在調用函數(shù)時同時給出形式參數(shù)和實際參數(shù)?!瓣P鍵字調用〞方式在函數(shù)具有多個參數(shù)是非常有用,因為解釋器能通過給出的關鍵字來匹配參數(shù)的值,所以這樣就允許參數(shù)缺失或者不按定義函數(shù)時的形式參數(shù)的順序提供實際參數(shù)?,F(xiàn)在舉一個例子,假設我們有一個函數(shù)叫做select(),它用來選擇學校中哪個年級的哪個班去清掃衛(wèi)生,我們給它定義了兩個參數(shù),第一個參數(shù)是x,表示年級,第二個參數(shù)是y,表示班級。其定義的偽碼如下所示:defselect(x,y):讓x年級y班的學生清掃衛(wèi)生如果我們想要3年級6班的學生去清掃衛(wèi)生,可以按照函數(shù)聲明中參數(shù)的定義順序,輸入相應的參數(shù),就可以調用這個函數(shù)了,如下所示:select(3,6)表示年級的參數(shù)x得到整數(shù)3,而表示年紀的參數(shù)y得到整數(shù)6。如果我們將上面的實際參數(shù)的順序換一下,如下所示:select(6,3)那么它就表示讓6年級3班的學生去清掃衛(wèi)生了。上面使用的標準方式來調用函數(shù)。下面我們再使用“關鍵字調用〞方式來調用同一個函數(shù)。我們還是讓3年級6班的學生去清掃衛(wèi)生,這時的調用形式如下所示:select(x=3,y=6)當然,我們也可以不按照函數(shù)聲明中的參數(shù)順序輸入,如下所示:select(y=6,x=3)這同樣是讓3年級6班的學生去清掃衛(wèi)生,而不是6年級3班的學生,因為這里我們顯式地將形參和實參聯(lián)系到了一起。此外,如果函數(shù)使用了缺省參數(shù)的話,我們可以省略某些實參,并通過關鍵字參數(shù)來指出提供的實參是賦給那些形參的。循序漸進學Python之函數(shù)入門〔3〕函數(shù)是Python編程的核心內(nèi)容之一,本文首先為讀者介紹什么是函數(shù),然后詳細介紹函數(shù)的定義和調用方法,最后,我們通過大量實例代碼詳細介紹了變量的作用域以及與此有關的global語句。四、缺省參數(shù)在定義函數(shù)時,我們可以用賦值符號給某些形參指定默認值,這樣當調用該函數(shù)的時候,如果調用方?jīng)]有為該參數(shù)提供值的話,那么使用默認值;如果調用該函數(shù)的時候為該參數(shù)提供了值的話,那么使用調用方提供的值——像這樣的參數(shù)我們稱之為缺省參數(shù)。需要注意的是默認參數(shù)在形式參數(shù)表中的位置,即默認參數(shù)必須在所有標準參數(shù)之后定義,例如:deff(arg1,arg2=2,arg3=3):print'arg1=',arg1print'arg2=',arg2print'arg3=',arg3這里,我們給后來個參數(shù)arg2和arg3指定了默認值,函數(shù)體的作用是輸出該函數(shù)三個參數(shù)的值。在交互式環(huán)境下執(zhí)行該函數(shù)的情況如下所示:
圖3
帶有缺省參數(shù)的函數(shù)現(xiàn)在我們對上述實驗做一些解釋。首先,我們看一下通過f〔10〕進行函數(shù)調用時的情形,因為arg1沒有缺省值,所以必須為它提供實參,所以f〔10〕中的實參10將傳遞給形參arg1,由于沒有給缺省參數(shù)arg2和arg3傳遞實參,所以它們采用默認值2和3。然后,我們又用了f〔10,10〕來調用函數(shù),這次第一個實參按順序給arg1,第二個實參按順序傳給arg2,所以這時缺省參數(shù)的值將是10,而非缺省值2。對于arg3,由于沒有給它傳遞實參,所以它的值依舊為缺省值3。最后,我們又用了f〔10,10,10〕來調用函數(shù),這次傳遞了三個實參,所以它們的值都會變成10,包括后兩個缺省參數(shù)。上面我們利用標準調用方式調用了缺省參數(shù)的函數(shù),下面我們看看對同一個函數(shù)使用“關鍵字調用〞方式的情形,如以下圖所示:
圖4
用“關鍵字調用〞方式調用帶有缺省參數(shù)的函數(shù)使用缺省參數(shù)的好處是,如果某個參數(shù)大局部情況下都取某個固定的值,那么就可以為這個參數(shù)定義一個默認值,這樣在以后使用這個函數(shù)時帶來很大的便利,因為我們大局部時間都不用給它傳參數(shù);如果偶爾情況有變,還可以給它傳遞更適合的值——真是一舉兩得呀!循序漸進學Python之函數(shù)入門〔4〕函數(shù)是Python編程的核心內(nèi)容之一,本文首先為讀者介紹什么是函數(shù),然后詳細介紹函數(shù)的定義和調用方法,最后,我們通過大量實例代碼詳細介紹了變量的作用域以及與此有關的global語句。五、局部變量和全局變量在Python中的任何變量都有其特定的作用域,比方在一個函數(shù)中定義的變量一般只能在該函數(shù)內(nèi)部使用,這些只能在程序的特定局部使用的變量我們稱之為局部變量;比方在一個文件頂部定義的變量可以供該文件中的任何函數(shù)調用,這些可以為整個程序所使用的變量稱為全局變量。上面是從空間的角度來考察變量的局部性和全局性,如果從時間的角度來看,不妨簡單地認為在程序運行的整個過程中,全局變量一直占據(jù)著內(nèi)存,并且它的值可以供所有函數(shù)訪問;而局部變量那么是只有在其所在函數(shù)被調用時才給它分配內(nèi)存,當函數(shù)返回時,其所占內(nèi)存就會被釋放,所以它只能供其所在的函數(shù)所訪問——換句話說,當某個函數(shù)退出時,其局部變量原先所占的內(nèi)存將被分配給其它函數(shù)的局部變量。打個不太貼切的比方,全局變量就好比您自己買的房子,通常一家人要在那里住上好幾十年,如果我要找您要債,我會老往您家里跑;而局部變量好似旅館,今天您租住這件房間,我可以到這個房間來找您,但是到明天再來這間房間的話,找到的可能就是別人了。下面提供一個例子來了解局部變量和全局變量,代碼如下所示:#-*-coding:cp936-*-#定義全局變量globalInt=9#定義一個函數(shù)defmyAdd():localInt=3#在函數(shù)中定義一個局部變量returnglobalInt+localInt#測試變量的局部性和全局性printmyAdd()printglobalIntprintlocalInt上述代碼中,我們定義了一個全局變量globalInt,該變量將在整個程序中有效;然后定義了一個函數(shù)myAdd(),并在這個函數(shù)中定義了一個局部變量localInt,該局部變量只能在函數(shù)myAdd()中有效。代碼的最后局部,我們先打印了函數(shù)的返回值,然后分別打印全局變量globalInt和局部變量localInt的值。例如代碼在IDLE中執(zhí)行的結果如下所示:
圖5
局部變量和全局變量用法舉例代碼的執(zhí)行結果說明,函數(shù)myAdd()既可以訪問其內(nèi)部自己定義的局部變量localInt,也可以使用在其外部定義的全局變量globalInt,所以調用該函數(shù)時返回的結果為12。然后打印了全局變量globalInt的值,其為9,這說明它全局可用。最后打印局部變量localInt時遇到了錯誤,錯誤提示說“l(fā)ocalInt〞沒有定義,這是因為局部變量localInt只能在定義它的函數(shù)myAdd()中有效,或者說可見,而超出函數(shù)范圍之外的代碼是看不到它的,根據(jù)先定義后使用的原那么,Python解釋器會認為該程序使用了未定義的變量名。讀者可能會問:如果我們定義了一個全局變量,然后又在函數(shù)中用同樣的名字定義了一個局部變量,換句話說,當局部變量和全局變量名稱發(fā)生沖突時,函數(shù)是將這個名稱作為全局變量對待呢還是作為局部變量對待?比方以下代碼:#-*-coding:cp936-*-#定義全局變量g=9#定義一個函數(shù)defmyf():g=3#定義一個局部變量,并且與前面定義的全局變量重名print'g=',g#測試變量g的局部性和全局性myf()上述代碼在IDLE中執(zhí)行的結果如下所示:
圖6
局部變量和全局變量的困惑乍一看,變量g在函數(shù)myf〔〕中的好似是作為局部變量使用,因為我們在這個函數(shù)中定義了局部變量g,并將變量g初始化為3,調用函數(shù)的結果顯示變量g的值為3,如上圖所示。但是仔細一想,事情好似又不是這樣,因為上面提到,全局變量在整個程序中有效,所以函數(shù)myf〔〕中的代碼g=3#定義一個局部變量,并且與前面定義的全局變量重名不僅可以理解為定義并初始化局部變量g,同時還可以看作是給全局變量g重新賦值。如果按照后一種解釋的話,結果也是一樣的。讀者可能被我搞糊涂了,不要緊,我們再做一個實驗就會弄清真相了,我們對上述代碼稍作修改,如下所示:#-*-coding:cp936-*-#定義全局變量g=9#定義一個函數(shù)defmyf():print'g=',gg=3#測試變量的局部性和全局性myf()這一次,我們首先在函數(shù)myf〔〕中輸出變量g的值,如果調用函數(shù)時打印的g的值為9的話,說明我們上面的第二種推測是正確的,否那么前一個推測是正確的。下面看看運行結果:
圖7
變量g在函數(shù)中被作為局部變量事實說明,在同一個源文件中,全局變量和局部變量同名時,在局部變量的作用范圍內(nèi),全局變量不起作用。因為要是在函數(shù)myf〔〕中變量g作為全局變量的話,這里肯定會輸出它的值,即9,然而事實并非如此,Python解釋器在最后一行,即UnboundLocalError:localvariable'g'referencedbeforeassignment明確指出,變量g是一個局部變量。之所以出現(xiàn)這樣的錯誤,是因為當Python在檢索一個變量名時,它首先在函數(shù)范圍內(nèi)尋找,如果在函數(shù)中沒有找到那個變量名,它才會到全局范圍內(nèi)尋找。但是這里在函數(shù)中找到了變量g的名字,但是我們在賦值前就引用了它,所以才導致了上面所示的UnboundLocalError異常。如果我們將上面的代碼再改一下,如下所示:#-*-coding:cp936-*-#定義全局變量g=9#定義一個函數(shù)defmyf():print'g=',g#g=3#測試變量的局部性和全局性myf()這里我們只是將函數(shù)myf〔〕中的g=3一句給注釋掉,就是讓它不起作用,其余局部一點也沒有改動。并且再次執(zhí)行該程序,結果如下:
圖8
變量g在函數(shù)中被作為局部變量這一次,Python在執(zhí)行函數(shù)myf〔〕時,由于在該函數(shù)中沒有找到變量g的定義〔注意,與C語言不同,Python在定義變量時不用在變量類型,所以有時給變量賦值和定義變量很難區(qū)分〕,所以到函數(shù)之外的地方查找它的定義。由于我們在程序的開頭局部有變量g的定義,并將其初始化為9,所以函數(shù)將變量g作為全局變量。循序漸進學Python之函數(shù)入門〔5〕函數(shù)是Python編程的核心內(nèi)容之一,本文首先為讀者介紹什么是函數(shù),然后詳細介紹函數(shù)的定義和調用方法,最后,我們通過大量實例代碼詳細介紹了變量的作用域以及與此有關的global語句。六、global語句從上面的介紹中我們可以看到,當函數(shù)內(nèi)部的變量跟外部的變量同名時,對于該函數(shù)來說,有時候該變量是全局變量,有時候該變量是局部變量,現(xiàn)在總結如下:◆如果在函數(shù)內(nèi)部對該變量進行了賦值操作,無論是在引用該變量之前還是在引用該變量之后,那么對于該函數(shù)來說,此變量是一個局部變量?!羧绻诤瘮?shù)內(nèi)部從未對該變量進行賦值操作,那么對于該函數(shù)來說,此變量是一個全局變量。讀者可能會問:這是不是說我們無法在函數(shù)內(nèi)部給一個全局變量賦值呢?比方,在程序中定義了一個全局變量a,如果在函數(shù)f〔〕中給變量a賦值的話,變量a就會被Python當成局部變量對待,所以全局變量的值還是沒變。例如代碼如下所示:#-*-coding:cp936-*-#定義全局變量a='hello'print'全局變量a=',a#定義一個函數(shù)deff():a='byby'print'函數(shù)f()中的變量a=',a#測試變量的局部性和全局性f()print'全局變量a=',a上述代碼的運行情況如下所示:
圖9
嘗試在函數(shù)中給全局變量賦值失敗從上圖可以看到,調用函數(shù)之前,變量a〔全局變量〕的值為字符串“hello〞,調用函數(shù)時變量a〔局部變量〕的值為字符串“byby〞,調用函數(shù)之后變量a〔全局變量〕的值仍然還是字符串“hello〞。結果很明顯,要想在函數(shù)中給全局變量賦值還得另外想方法。事實上,我們可以通過global語句來到達這個目的。global語句的作用是將某些變量聲明為全局變量,它的語法形式如下所示:global變量名注意,這里的變量名可以是一個,也可以使多個。當關鍵詞global后面跟隨多個變量名稱時,各名稱之間要用逗號分隔開來。當我們在函數(shù)中將某個變量聲明為全局變量〔即告訴P
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
評論
0/150
提交評論