【正文】
表中引入函數(shù)名。作為用戶(hù)定義函數(shù),函數(shù)名有一個(gè)為解釋器認(rèn)可的類(lèi)型值。這個(gè)值可以 賦給其它命名,使其能句做為一個(gè)函數(shù)來(lái)使用。這就像一個(gè)重命名機(jī)制: fibfunction object at 10042ed0 f = fib f(100)1 1 2 3 5 8 13 21 34 55 89你可能認(rèn)為fib不是一個(gè)函數(shù)(function),而是一個(gè)過(guò)程(procedure)。Python和C一樣,過(guò)程只是一個(gè)沒(méi)有返 回值的函數(shù)。實(shí)際上,從技術(shù)上講,過(guò)程也有一個(gè)返回值,雖然是一個(gè)不討人喜歡的。這個(gè)值被稱(chēng)為 None(這是一個(gè)內(nèi)置命名)。如果一個(gè)值只是None的話(huà),通常解釋器不會(huì)寫(xiě)一個(gè)None出來(lái),如果你真想要看它的 話(huà),可以這樣做: print fib(0) None以下示列演示了如何從函數(shù)中返回一個(gè)包含菲波那契數(shù)列的數(shù)值鏈表,而不是打印它: def fib2(n): return Fibonacci series up to n... Return a list containing the Fibonacci series up to n.... result = []... a, b = 0, 1... while b n:... (b) see below... a, b = b, a+b... return result... f100 = fib2(100) call it f100 write the result[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]和以前一樣,這個(gè)例子演示了一些新的Python功能:return語(yǔ)句從函數(shù)中返回一個(gè)值,不帶表達(dá)式的return返回None。過(guò)程結(jié)束后也會(huì)返回None。(b)稱(chēng)為鏈表對(duì)象result的一個(gè)方法(method)。方法是一個(gè)“屬于”某個(gè)對(duì)象的函數(shù),它 ,這里的obj是某個(gè)對(duì)象(可能是一個(gè)表達(dá)式),methodename是某個(gè)在該對(duì)象類(lèi)型定義中的方法的命名。 不同的類(lèi)型定義不同的方法。不同類(lèi)型可能有同樣名字的方法,但不會(huì)混淆。(當(dāng)你定義自己的對(duì)象類(lèi)型和方法時(shí),可能會(huì)出現(xiàn)這種情況,本指南后面的章節(jié)會(huì)介紹如何使用類(lèi))。示例中演示的append()方法由鏈表對(duì)象定義,它向鏈表中加入一個(gè)新元素。在示例中它等同于result = result + [b],不過(guò)效率更高。 深入函數(shù)定義有時(shí)需要定義參數(shù)個(gè)數(shù)可變的函數(shù)。有三個(gè)方法可以做到,我們可以組合使用它們。 參數(shù)默認(rèn)值最有用的形式是給一個(gè)或多個(gè)參數(shù)指定默認(rèn)值。這樣創(chuàng)建的函數(shù)可以在調(diào)用時(shí)使用更少的參數(shù)。def ask_ok(prompt, retries=4, plaint=39。Yes or no, please!39。):while True:ok = raw_input(prompt)if ok in (39。y39。, 39。ye39。, 39。yes39。): return 1if ok in (39。n39。, 39。no39。, 39。nop39。, 39。nope39。): return 0 retries = retries 1if retries 0: raise IOError, 39。refusenik user39。 print plaint這個(gè)函數(shù)還可以用以下的方式調(diào)用:ask_ok(39。Do you really want to quit?39。),或者像這樣:ask_ok(39。OK to overwrite the file?39。,2)。默認(rèn)值在函數(shù)定義段被解析,如下所示:i = 5def f(arg=i):print argi = 6 f()will print 5.重要警告:默認(rèn)值只會(huì)解析一次。當(dāng)默認(rèn)值是一個(gè)可變對(duì)象,諸如鏈表、字典或大部分類(lèi)實(shí)例時(shí),會(huì)產(chǎn)生一些 差異。例如,以下函數(shù)在后繼的調(diào)用中會(huì)積累它的參數(shù)值:def f(a, L=[]): (a) return Lprint f(1) print f(2) print f(3)這會(huì)打印出:[1][1, 2][1, 2, 3]如果你不想在不同的函數(shù)調(diào)用之間共享參數(shù)默認(rèn)值,可以如下面的實(shí)例一樣編寫(xiě)函數(shù):def f(a, L=None):if L is None: L = [](a)return L 參數(shù)關(guān)鍵字函數(shù)可以通過(guò)參數(shù)關(guān)鍵字的形式來(lái)調(diào)用,形如“keyword = value”。例如,以下的函數(shù):def parrot(voltage, state=39。a stiff39。, action=39。voom39。, type=39。Norwegian Blue39。):print This parrot wouldn39。t, action,print if you put, voltage, Volts through it. print Lovely plumage, the, typeprint It39。s, state, !可以用以下的任一方法調(diào)用:parrot(1000)parrot(action = 39。VOOOOOM39。, voltage = 1000000)parrot(39。a thousand39。, state = 39。pushing up the daisies39。)parrot(39。a million39。, 39。bereft of life39。, 39。jump39。)不過(guò)以下幾種調(diào)用是無(wú)效的:parrot() required argument missing(缺少必要參數(shù))parrot(voltage=, 39。dead39。) nonkeyword argument following keyword(在關(guān)鍵字后面有非關(guān)鍵字參數(shù))parrot(110, voltage=220) duplicate value for argument(對(duì)參數(shù)進(jìn)行了重復(fù)賦值)parrot(actor=39。John Cleese39。) unknown keyword(未知關(guān)鍵字)通常,參數(shù)列表中的每一個(gè)關(guān)鍵字都必須來(lái)自于形式參數(shù),每個(gè)參數(shù)都有對(duì)應(yīng)的關(guān)鍵字。形式參數(shù)有沒(méi)有默認(rèn) 值并不重要。實(shí)際參數(shù)不能一次賦多個(gè)值--形式參數(shù)不能在同一次調(diào)用中同時(shí)使用位置和關(guān)鍵字綁定值。這 里有一個(gè)例子演示了在這種約束下所出現(xiàn)的失敗情況: def function(a):... pass... function(0, a=0)Traceback (most recent call last): File stdin, line 1, in ?TypeError: function() got multiple values for keyword argument 39。a39。引入一個(gè)形如 **name 的參數(shù)時(shí),它接收一個(gè)字典,該字典包含了所有未出現(xiàn)在形式參數(shù)列表中的關(guān)鍵字參 數(shù)。這里可能還會(huì)組合使用一個(gè)形如 *name 的形式參數(shù),它接收一個(gè)拓?fù)洌ㄏ乱还?jié)中會(huì)詳細(xì)介紹),包含了所 有沒(méi)有出現(xiàn)在形式參數(shù)列表中的參數(shù)值。(*name 必須在 **name 之前出現(xiàn)) 例如,我們這樣定義一個(gè)函數(shù):def cheeseshop(kind, *arguments, **keywords):print Do you have any, kind, 39。?39。print I39。m sorry, we39。re all out of, kind for arg in arguments: print argprint 39。39。*40keys = ()()for kw in keys: print kw, 39。:39。, keywords[kw]它可以像這樣調(diào)用:cheeseshop(39。Limburger39。, It39。s very runny, sir., It39。s really very, VERY runny, sir., client=39。John Cleese39。, shopkeeper=39。Michael Palin39。, sketch=39。Cheese Shop Sketch39。)當(dāng)然它會(huì)按如下內(nèi)容打印: Do you have any Limburger ? I39。m sorry, we39。re all out of LimburgerIt39。s very runny, sir.It39。s really very, VERY runny, sir. client : John Cleeseshopkeeper : Michael Palin sketch : Cheese Shop Sketch注意sort()方法在關(guān)鍵字字典內(nèi)容打印前被調(diào)用,否則的話(huà),打印參數(shù)時(shí)的順序是未定義的。 可變參數(shù)表最后,一個(gè)最不常用的選擇是可以讓函數(shù)調(diào)用可變個(gè)數(shù)的參數(shù)。這些參數(shù)被包裝進(jìn)一個(gè)拓?fù)?。在這些可變個(gè)數(shù) 的參數(shù)之前,可以有零到多個(gè)普通的參數(shù):def fprintf(file, format, *args):(format % args) Lambda 形式出于適當(dāng)?shù)男枰?,有幾種通常在功能性語(yǔ)言和Lisp中出現(xiàn)的功能加入到了Python。通過(guò)lambda關(guān)鍵字,可以創(chuàng) 建很小的匿名函數(shù)。這里有一個(gè)函數(shù)返回它的兩個(gè)參數(shù)的和:“l(fā)ambda a, b: a+b”。 Lambda 形式可以用于任何 需要的函數(shù)對(duì)象。出于語(yǔ)法限制,它們只能有一個(gè)單獨(dú)的表達(dá)式。語(yǔ)義上講,它們只是普通函數(shù)定義中的一個(gè) 語(yǔ)法技巧。類(lèi)似于嵌套函數(shù)定義,lambda形式可以從包含范圍內(nèi)引用變量: def make_incrementor(n):... return lambda x: x + n... f = make_incrementor(42) f(0)42 f(1)43 文檔字符串這里介紹文檔字符串的概念和格式。 第一行應(yīng)該是關(guān)于對(duì)象用途的簡(jiǎn)介。簡(jiǎn)短起見(jiàn),不用明確的陳述對(duì)象名或類(lèi)型,因?yàn)樗鼈兛梢詮膭e的途徑了解到(除非這個(gè)名字碰巧就是描述這個(gè)函數(shù)操作的動(dòng)詞)。這一行應(yīng)該以大寫(xiě)字母開(kāi)頭,以句號(hào)結(jié)尾。如果文檔字符串有多行,第二行應(yīng)該空出來(lái),與接下來(lái)的詳細(xì)描述明確分隔。接下來(lái)的文檔應(yīng)該有一或多段描 述對(duì)象的調(diào)用約定、邊界效應(yīng)等。Python的解釋器不會(huì)從多行的文檔字符串中去除縮進(jìn),所以必要的時(shí)候應(yīng)當(dāng)自己清除縮進(jìn)。這符合通常的習(xí) 慣。第一行之后的第一個(gè)非空行決定了整個(gè)文檔的縮進(jìn)格式。(我們不用第一行是因?yàn)樗ǔ>o靠著起始的引 號(hào),縮進(jìn)格式顯示的不清楚。)留白“相當(dāng)于”是字符串的起始縮進(jìn)。 每一行都不應(yīng)該有縮進(jìn),如果有縮進(jìn)的 話(huà),所有的留白都應(yīng)該清除掉。相當(dāng)于留白就是驗(yàn)證后的制表符擴(kuò)展(通常是8個(gè)空格)。(這一段譯得不 通,有疑問(wèn)的讀者請(qǐng)參見(jiàn)原文--譯者)以下是一個(gè)多行文檔字符串的示例: def my_function():... Do nothing, but document it....... No, really, it doesn39。t do anything.... ... pass... print my_function. doc Do nothing, but document it.No, really, it doesn39。t do anything.腳注... 對(duì)象)。 實(shí)際上,說(shuō)是調(diào)用對(duì)象引用更合適,因?yàn)槿绻麄魅胍粋€(gè)可變對(duì)象,調(diào)用者可以得到被調(diào)用者產(chǎn)生的任何 改變(如鏈表中插入了子項(xiàng))。Python 指南向前:3. 初步認(rèn)識(shí) Python 向上:Python 指南 向后:5. 數(shù)據(jù)結(jié)構(gòu)Release , documentation updated on July 29, 2003.See About this document... for information on suggesting changes.Python中文社區(qū)5. 數(shù)據(jù)結(jié)構(gòu)file:///Users/moon/Ining/py/[09521 ??08:01:21]Python中文社區(qū)Python指南向前: 4. 深入流程控制 向上: Python 指南 向后: 6. 模塊子目錄 深入鏈表 把鏈表當(dāng)作堆棧使用 把鏈表當(dāng)作隊(duì)列使用 函數(shù)化編程工具 鏈表推導(dǎo)式 del 語(yǔ)句 元組(Tuples) 和 序列(Sequences) 字典(Dictionaries) 循環(huán)技巧 深入條件控制 比較序列(Sequences)和其它類(lèi)型5. 數(shù)據(jù)結(jié)構(gòu)本章節(jié)深入講述一些你已經(jīng)學(xué)習(xí)過(guò)的東西,并且還加入了新的內(nèi)容。 深入鏈表鏈表類(lèi)型有很多方法,這里是鏈表類(lèi)型的所有方法:append(x)把一個(gè)元素添加到鏈表的結(jié)尾,相當(dāng)于 a[len(a):] = [x]。extend(L)通過(guò)添加指定鏈表的所有元素