3.3 返回值
函數(shù)并非總是直接顯示輸出,相反,它可以處理一些數(shù)據(jù),并返回一個(gè)或一組值。在函數(shù)中,可使用return 語句將值返回到調(diào)用函數(shù)的代碼行。
3.3.1 返回簡單值
實(shí)例:函數(shù),它接受名和姓并返回整潔的姓名。
def get_formatted_name(first_name,last_name):
? ? '''返回格式化后的姓名'''
? ? full_name = first_name + ' ' + last_name
? ? return full_name
musician = get_formatted_name('connie','niu').title()
print(musician)
3.3.2 讓實(shí)參變成可選
需要讓實(shí)參變成可選的,這樣使用函數(shù)的人就只需在必要時(shí)才提供額外的信息。可使用默認(rèn)值來讓實(shí)參變成可選的。例如:擴(kuò)展函數(shù)get_formatted_name() ,使其還處理中間名。由于并非所有的人都有中間名,但如果你調(diào)用這個(gè)函數(shù)時(shí)只提供了名和姓,它將不能正確地運(yùn)行。為讓get_formatted_name() 在沒有提供中間名時(shí)依然可行,可給實(shí)參middle_name 指定一個(gè)默認(rèn)值---空字符串,并將其移到形參列表的末尾。
def get_formatted_name(first_name, last_name, middle_name=''):
? ? """返回整潔的姓名"""
? ? if middle_name:
? ? ? ? full_name = first_name + ' ' + middle_name + ' ' + last_name
? ? else:
? ? ? ? full_name = first_name + ' ' + last_name
? ? return full_name.title()
musician = get_formatted_name('jimi', 'hendrix')
print(musician)
musician = get_formatted_name('john', 'hooker', 'lee')
print(musician)
示例詳細(xì)說明:
? 姓名是根據(jù)名、姓、中間名三個(gè)可能提供的部分創(chuàng)建的。由于人都有名和姓,因此在函數(shù)定義中首先列出了這兩個(gè)形參。中間名是可選的,因此在函數(shù)定義中最后列出該形參,并將其默認(rèn)值設(shè)置為空字符串(再次強(qiáng)調(diào):使用參數(shù)使用默認(rèn)值,多個(gè)傳遞時(shí)是按照位置參數(shù)解析,即嚴(yán)格依據(jù)參數(shù)順序);
? 在函數(shù)體中,檢查是否提供了中間名。Python將非空字符串解讀為True ,因此如果函數(shù)調(diào)用中提供了中間名,if middle_name 將為True判斷;
? 如果提供了中間名,就將名、中間名和姓合并為姓名;
? 如果沒有提供中間名,middle_name 將為空字符串,導(dǎo)致if 測試未通過,進(jìn)而執(zhí)行else 代碼塊,只使用名和姓來生成姓名;
? 然后將其修改為首字母大寫格式,并返回到函數(shù)調(diào)用行;
? 在函數(shù)調(diào)用行,將返回的值存儲(chǔ)在變量musician 中;然后將這個(gè)變量的值打印出來。
3.3.3 返回字典
函數(shù)可返回任何類型的值,包括列表和字典等較復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。
實(shí)例:定義函數(shù)接受姓名的組成部分,并返回一個(gè)表示人的字典。
def build_person(first_name, last_name):
? ? """返回一個(gè)字典,其中包含有關(guān)一個(gè)人的信息"""
? ? person = {'first': first_name, 'last': last_name}
? ? return person
musician = build_person('jimi', 'hendrix')
print(musician)
3.4 傳遞列表
向函數(shù)傳遞列表很有用,這種列表包含的可能是名字、數(shù)字或更復(fù)雜的對象(如字典)。將列表傳遞給函數(shù)后,函數(shù)就能直接訪問其內(nèi)容。
實(shí)例:假設(shè)有一個(gè)用戶列表,將列表傳遞給一個(gè)名為greet_users() 的函數(shù),在函數(shù)中問候列表中的每個(gè)人。
def greet_users(names):
? ? """向列表中的每位用戶都發(fā)出簡單的問候"""
? ? for name in names:
? ? ? ? msg = "Hello, " + name.title() + "!"
? ? ? ? print(msg)
usernames = ['hannah', 'ty', 'margot']
greet_users(usernames)
3.4.1 在函數(shù)中修改列表
將列表傳遞給函數(shù),在函數(shù)中對這個(gè)列表所做的任何修改都是永久性的,可高效地處理大量的數(shù)據(jù)。
def print_models(unprinted_designs, completed_models):
? ? """
? ? 模擬打印每個(gè)設(shè)計(jì),直到?jīng)]有未打印的設(shè)計(jì)為止
? ? 打印每個(gè)設(shè)計(jì)后,都將其移到列表completed_models中
? ? """
? ? while unprinted_designs:
? ? ? ? current_design = unprinted_designs.pop()
? ? ? ? #模擬根據(jù)設(shè)計(jì)制作3D打印模型的過程
? ? ? ? print("Printing model: " + current_design)
? ? ? ? completed_models.append(current_design)
def show_completed_models(completed_models):
? ? """顯示打印好的所有模型"""
? ? print("\nThe following models have been printed:")
? ? for completed_model in completed_models:
? ? ? ? print(completed_model)
unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = []
print_models(unprinted_designs,completed_models)
show_completed_models(completed_models)
示例詳解:
? 我們定義了函數(shù)print_models() ,它包含兩個(gè)形參:一個(gè)需要打印的設(shè)計(jì)列表和一個(gè)打印好的模型列表。給定這兩個(gè)列表,這個(gè)函數(shù)模擬打印每個(gè)設(shè)計(jì)的過程:將設(shè)計(jì)逐個(gè)地從未打印的設(shè)計(jì)列表中取出,并加入到打印好的模型列表中。
? 我們定義了函數(shù)show_completed_models() ,它包含一個(gè)形參:打印好的模型列表。給定這個(gè)列表,函數(shù)show_completed_models() 顯示打印出來的每個(gè)模型的名稱。
? 接下來為主程序,創(chuàng)建一個(gè)未打印的設(shè)計(jì)列表,還創(chuàng)建了一個(gè)空列表,用于存儲(chǔ)打印好的模型。調(diào)用print_models() 并向它傳遞兩個(gè)列表,并完成相關(guān)處理;
? 調(diào)用show_completed_models() ,并將打印好的模型列表傳遞給它,讓其能夠指出打印了哪些模型。
這個(gè)程序還演示了這樣一種理念,即每個(gè)函數(shù)都應(yīng)只負(fù)責(zé)一項(xiàng)具體的工作。第一個(gè)函數(shù)打印每個(gè)設(shè)計(jì),而第二個(gè)顯示打印好的模型;這優(yōu)于使用一個(gè)函數(shù)來完成兩項(xiàng)工作。編寫函數(shù)時(shí),如果你發(fā)現(xiàn)它執(zhí)行的任務(wù)太多,請嘗試將這些代碼劃分到兩個(gè)函數(shù)中。別忘了,總是可以在一個(gè)函數(shù)中調(diào)用另一個(gè)函數(shù),這有助于將復(fù)雜的任務(wù)劃分成一系列的步驟。這樣組織代碼讓程序更容易擴(kuò)展和維護(hù)。
3.4.2 禁止函數(shù)修改列表
有時(shí)候,需要禁止函數(shù)修改列表。例如,像前一個(gè)示例那樣,程序執(zhí)行完成,未打印的設(shè)計(jì)列表會(huì)被清空,若希望保留原來的未打印的設(shè)計(jì)列表,以供備案。則可將列表的副本傳遞給函數(shù):print_models(unprinted_designs[:], completed_models)
函數(shù)print_models()使用的是列表unprinted_designs 的副本,而不是列表本身。
雖然向函數(shù)傳遞列表的副本可保留原始列表的內(nèi)容,但除非有充分的理由需要傳遞副本,否則還是應(yīng)該將原始列表傳遞給函數(shù),因?yàn)闀?huì)消耗更多的時(shí)間和內(nèi)存。