新聞中心
定義函數(shù)

網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了石嘴山免費(fèi)建站歡迎大家使用!
我們通過斐波那契數(shù)列來理解定義函數(shù)
>>> def fib(n): # 將斐波那契數(shù)列打印到 n ... """將斐波那契數(shù)列打印到 n""" ... a, b = 0, 1 ... while a < n: ... print(a, end=' ') ... a, b = b, a+b ... print() ... >>> # 調(diào)用上面定義的函數(shù) ... fib(2000) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
關(guān)鍵字 def 引入了一個(gè)函數(shù)定義 。其后面必須跟隨有函數(shù)的名稱以及用括號包起來的一系列參數(shù)。構(gòu)成函數(shù)體的語句從下一行開始,并且必須縮進(jìn)。
函數(shù)體的第一個(gè)語句可以是一個(gè)字符串常量,這個(gè)字符串常量就是這個(gè)函數(shù)的文檔字符串,或者說是 docstring ,有很多工具可以用于在線或者可打印文檔的自動化生成,或者可以讓用戶交互地在代碼中瀏覽文檔;在代碼中寫文檔字符串是比較好的實(shí)踐,所以請養(yǎng)成寫文檔字符串的習(xí)慣。
函數(shù)的執(zhí)行引入了一個(gè)新的符號表用于存儲函數(shù)的局部變量。更準(zhǔn)確地說,在函數(shù)內(nèi)的所有變量賦值都會被存儲到這張局部符號表中;所以在查找一個(gè)變量的引用時(shí),會先查找局部符號表,然后查找閉包函數(shù)的局部符號表,接著是全局符號表,最后才是內(nèi)置名稱表。因此,盡管可能在函數(shù)中引用全局變量,但在函數(shù)中無法對全局變量直接進(jìn)行賦值(除非用 global 語句來定義一個(gè)變量)
當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),函數(shù)參數(shù)被引入到局部符號表中;因此,參數(shù)是通過 按值傳遞 的方式來傳遞的(這個(gè)值表示一個(gè)對象的 引用 ,而不是該對象的值)。[1] 當(dāng)在一個(gè)函數(shù)中調(diào)用另外一個(gè)函數(shù)時(shí),將會為這次調(diào)用創(chuàng)建一個(gè)新的局部符號表。
一個(gè)函數(shù)定義將會在當(dāng)前符號表中引入函數(shù)的名稱。這個(gè)函數(shù)的名稱對應(yīng)的值的類型會被解釋器解釋為用戶定義的函數(shù)。這個(gè)值可以被賦值給另外一個(gè)名稱,并且將這名稱可以當(dāng)作一個(gè)函數(shù)來使用。這是一種常用的重命名機(jī)制:
>>> fib>>> f = fib >>> f(100) 0 1 1 2 3 5 8 13 21 34 55 89
默認(rèn)參數(shù)值
最常用的形式是為一個(gè)或多個(gè)參數(shù)指定默認(rèn)值。這樣,函數(shù)可以以少于其定義的參數(shù)被調(diào)用。比如:
def ask_ok(prompt, retries=4, reminder='Please try again!'):
while True:
ok = input(prompt)
if ok in ('y', 'ye', 'yes'):
return True
if ok in ('n', 'no', 'nop', 'nope'):
return False
retries = retries - 1
if retries < 0:
raise ValueError('invalid user response')
print(reminder)該函數(shù)可以有幾種不同的調(diào)用方式:
只指定強(qiáng)制的參數(shù)
參數(shù): ask_ok('Do you really want to quit?')
提供一個(gè)可選參數(shù)
參數(shù): ask_ok('OK to overwrite the file?', 2)
或者給定全部的參數(shù)
參數(shù): ask_ok('OK to overwrite the file?', 2, 'Come on, onlyyes or no!')
上述例子順便也提及了 in 關(guān)鍵字。它是用來測試某個(gè)特定值是否在一個(gè)序列中。
默認(rèn)值是在定義函數(shù)時(shí)的 “定義過程中” (defining )的范圍內(nèi)評估的(函數(shù)參數(shù)默認(rèn)值是個(gè)變量的話,要根據(jù)函數(shù)定義前變量的值來確定參數(shù)默認(rèn)值), 所以,
i = 5 def f(arg=i): print(arg) i = 6 f()
會打印 5.
關(guān)鍵字參數(shù)
形如 kwarg=value 形式的參數(shù)是 關(guān)鍵字參數(shù)。例如,以下函數(shù):
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
print("-- This parrot wouldn't", action, end=' ')
print("if you put", voltage, "volts through it.")
print("-- Lovely plumage, the", type)
print("-- It's", state, "!")接收一個(gè)必選參數(shù) (voltage ) 和三個(gè)可選參數(shù)( state,action, 和 type )。這個(gè)函數(shù)下方式調(diào)用:
parrot(1000) # 一個(gè)位置參數(shù)
parrot(voltage=1000) # 一個(gè)關(guān)鍵字參數(shù)
parrot(voltage=1000000, action='VOOOOOM') # 2個(gè)關(guān)鍵字參數(shù)
parrot(action='VOOOOOM', voltage=1000000) # 2個(gè)關(guān)鍵字參數(shù)
parrot('a million', 'bereft of life', 'jump') # 3個(gè)位置參數(shù)
parrot('a thousand', state='pushing up the daisies') # 一個(gè)位置參數(shù),一個(gè)關(guān)鍵字參數(shù)但是下列的所有調(diào)用方式都是無效的:
parrot() # 必選參數(shù)缺失 parrot(voltage=5.0, 'dead') # 非關(guān)鍵字參數(shù)在關(guān)鍵字參數(shù)后面 parrot(110, voltage=220) # 同一參數(shù)重復(fù)賦值 parrot(actor='John Cleese') # 未知關(guān)鍵字參數(shù)
在函數(shù)調(diào)用中,關(guān)鍵字參數(shù)必須遵循參數(shù)位置。傳遞的所有關(guān)鍵字參數(shù)必須跟函數(shù)接受的其中一個(gè)參數(shù)相匹配。(例如: actor 在函數(shù) parrot 中不是一個(gè)有效的參數(shù)),并且它們的順序并不重要。這同樣也包括那些非必選參數(shù) (例如 parrot(voltage=1000) 同樣有效)。沒有參數(shù)可能多次獲取一個(gè)值。下例就是因此而失敗的:
>>> def function(a): ... pass ... >>> function(0, a=0) Traceback (most recent call last): File "", line 1, in TypeError: function() got multiple values for keyword argument 'a'
當(dāng)最后存在 **name 形式的參數(shù)時(shí),它最后會接收一個(gè)字典,(參見 Mapping Types --- dict) 包含所有除了和形式參數(shù)相對應(yīng)的關(guān)鍵字參數(shù)。這可以與 * name 形式的形式參數(shù)(在下一小節(jié)中描述)結(jié)合,該參數(shù)接收包含正式參數(shù)列表之外的位置參數(shù)的元組。 (*name 必須出現(xiàn)在 **name 之前。) 例如,我們?nèi)绻x一個(gè)如下函數(shù):
def cheeseshop(kind, *arguments, **keywords):
print("-- Do you have any", kind, "?")
print("-- I'm sorry, we're all out of", kind)
for arg in arguments:
print(arg)
print("-" * 40)
for kw in keywords:
print(kw, ":", keywords[kw])它可以像這樣調(diào)用:
cheeseshop("Limburger", "It's very runny, sir.",
"It's really very, VERY runny, sir.",
shopkeeper="Michael Palin",
client="John Cleese",
sketch="Cheese Shop Sketch")可變參數(shù)
最后,最不常用的指定參數(shù)的選項(xiàng)是可變數(shù)量的參數(shù)。這些參數(shù)將被組裝成一個(gè)元組 (參見 元組和序列) 。在可變參數(shù)之前,可能會出現(xiàn)零個(gè)或多個(gè)正常參數(shù)。
def write_multiple_items(file, separator, *args): file.write(separator.join(args))
分離參數(shù)列表
當(dāng)輸入的參數(shù)已經(jīng)是列表或元組形式而為了調(diào)用其中單獨(dú)的位置參數(shù)時(shí),將會出現(xiàn)與上面相反的情況。例如內(nèi)置函數(shù) range() 需要有獨(dú)立的 start 和 stop 參數(shù)。如果輸入的時(shí)候不是獨(dú)立的參數(shù),則需要用 * 操作符來將參數(shù)從列表或者元組里面提取出來:
>>> list(range(3, 6)) # 正常利用參數(shù)調(diào)用函數(shù) [3, 4, 5] >>> args = [3, 6] >>> list(range(*args)) # 從列表中提取參數(shù)來調(diào)用函數(shù) [3, 4, 5]
Lambda 表達(dá)式
我們可以使用 lambda關(guān)鍵字來創(chuàng)建小型匿名函數(shù)。此函數(shù)會返回其兩個(gè)參數(shù)的和:lambda a,b:a + b??梢栽谌魏涡枰瘮?shù)對象的場合使用 Lambda 函數(shù)。它們在語法上僅限于單個(gè)表達(dá)式。從語義上講,它們只是普通函數(shù)定義的語法糖。與嵌套函數(shù)定義類似,lambda 函數(shù)可以從包含它的上下文中引用變量:
>>> def make_incrementor(n): ... return lambda x: x + n ... >>> f = make_incrementor(42) >>> f(0) 42 >>> f(1) 4
網(wǎng)站欄目:創(chuàng)新互聯(lián)Python教程:小白必看的Python函數(shù)講解
網(wǎng)址分享:http://www.5511xx.com/article/cdpispi.html


咨詢
建站咨詢
