閱讀《Python編程從入門(mén)到實(shí)踐》Day08

第八章(二)

3欧引、返回值

函數(shù)返回的值被稱(chēng)為返回值听系。在函數(shù)中,可使用return語(yǔ)句將值返回到調(diào)用函數(shù)的代碼行航棱。返回值可以將程序中大部分繁重的工作移到函數(shù)中去完成睡雇,從而簡(jiǎn)化程序。

(1)返回簡(jiǎn)單值
def get_formatted_name(first_name, last_name):
    full_name = first_name + ' ' + last_name
    return full_name.title()
musician = get_formatted_name('jimi', 'hendrix')
print(musician)
# 輸出:
Jimi Hendrix

這個(gè)函數(shù)將接收到的姓名整潔地重新輸出饮醇。

(2)讓實(shí)參變成可選的

讓實(shí)參變成可選的它抱,可以讓使用函數(shù)的人只有在必要時(shí)才提供額外的信息∑蛹瑁可使用默認(rèn)值來(lái)讓實(shí)參變成可選的观蓄。

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)
# 輸出:
Jimi Hendrix
John Lee Hooker

在上面的函數(shù)中添加了一個(gè)中間名,若沒(méi)有給定默認(rèn)值祠墅,調(diào)用時(shí)只提供名和姓侮穿,Python會(huì)報(bào)錯(cuò)。而給它一個(gè)空字符串作為默認(rèn)值就不會(huì)報(bào)錯(cuò)毁嗦。給了默認(rèn)值的參數(shù)必須移到?jīng)]有默認(rèn)值的參數(shù)后面亲茅。在調(diào)用函數(shù)的時(shí)候,有默認(rèn)值的形參是否傳遞實(shí)參,完全在于調(diào)用的人是否需要克锣∫鹚啵可選值讓函數(shù)能夠處理各種不同的情形的同時(shí),確保函數(shù)調(diào)用盡可能簡(jiǎn)單娶耍。

(3)返回字典

函數(shù)可返回任何類(lèi)型的值,包括列表和字典等較為復(fù)雜的的數(shù)據(jù)結(jié)構(gòu)饼酿。

def build_person(first_name, last_name):
    person = {'first': first_name, 'last': last_name}
    return person
musician = build_person('jimi', 'hendrix')
print(musician)
# 輸出:
{'first': 'jimi', 'last': 'hendrix'}

在這個(gè)函數(shù)中榕酒,你可以輕松的擴(kuò)展這個(gè)函數(shù),使其接收可選值故俐。

def build_person(first_name, last_name, age=''):
    person = {'first': first_name, 'last': last_name}
    if age:
        person['age'] = age
    return person
musician = build_person('jimi', 'hendrix', age=27)
print(musician)
# 輸出:
{'first': 'jimi', 'last': 'hendrix', 'age': 27}

在這里新增了一個(gè)可選的形參age想鹰。同理也可以進(jìn)行其他信息的擴(kuò)展。

(4)結(jié)合使用函數(shù)和while循環(huán)
def get_formatted_name(first_name, last_name):
    full_name = first_name + ' ' + last_name
    return full_name.title()
while True:
    print("\nPlease tell me your name:")
    print("(enter 'q' at any time to quit)")
    f_name = input("First name: ")
    if f_name == 'q':
        break
    l_name = input("Last name: ")
    if l_name == 'q':
        break
    formatted_name = get_formatted_name(f_name, l_name)
    print("\nHello, " + formatted_name + "!")
# 輸出:
Please tell me your name:
(enter 'q' at any time to quit)
First name: eric
Last name: matthes

Hello, Eric Matthes!

Please tell me your name:
(enter 'q' at any time to quit)
First name: q

4药版、傳遞列表

將列表傳遞給函數(shù)后辑舷,函數(shù)就能直接訪問(wèn)其內(nèi)容。用函數(shù)訪問(wèn)列表中的每個(gè)人:

def greet_users(names):
    for name in names:
        msg = "Hello, " + name.title() + "!"
        print(msg)
usernames = ['hannah', 'ty', 'margot']
greet_users(usernames)
# 輸出:
Hello, Hannah!
Hello, Ty!
Hello, Margot!
(1)在函數(shù)中修改列表

將列表傳遞給函數(shù)后槽片,函數(shù)就可對(duì)其進(jìn)行修改何缓。在函數(shù)中對(duì)這個(gè)列表所做的任何修改都是永久的。

def print_models(unprinted_designs, completed_models):
    while unprinted_designs:
        current_design = unprinted_designs.pop()
        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)
# 輸出:
Printing model: dodecahedron
Printing model: robot pendant
Printing model: iphone case

The following models have been printed:
dodecahedron
robot pendant
iphone case

這個(gè)例子演示了一種理念还栓,即每個(gè)函數(shù)都應(yīng)只負(fù)責(zé)一項(xiàng)具體的工作碌廓。編寫(xiě)函數(shù)時(shí),如果你發(fā)現(xiàn)它執(zhí)行的任務(wù)太多剩盒,可以嘗試將它分到兩個(gè)函數(shù)中谷婆,而且總是可以在一個(gè)函數(shù)中調(diào)用另一個(gè)函數(shù),這有助于將復(fù)雜的任務(wù)劃分成一系列的步驟辽聊。

(2)禁止函數(shù)修改列表

當(dāng)你執(zhí)行修改列表后纪挎,還需要使用未修改之前的列表時(shí),可以將傳遞給函數(shù)的列表改為列表的副本而不是原件跟匆,這樣函數(shù)所做的任何修改都只影響副本异袄,而絲毫不影響原件。
用切片表示法[:]創(chuàng)建列表的副本玛臂。如:

print_models(unprinted_designs[:], completed_models)

雖然向函數(shù)傳遞列表的副本可保留原始列表的內(nèi)容隙轻,但除非有充分的理由需要傳遞副本,否則還是應(yīng)該將原始列表傳遞給函數(shù)垢揩,因?yàn)樽尯瘮?shù)使用現(xiàn)成列表可避免花時(shí)間和內(nèi)存創(chuàng)建副本玖绿,從而提高效率,在處理大型列表時(shí)尤其如此叁巨。

5斑匪、傳遞任意數(shù)量的實(shí)參

Python允許函數(shù)從調(diào)用語(yǔ)句中收集任意數(shù)量的實(shí)參。

def make_pizza(*toppings):
    print(toppings)

make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')
# 輸出:
('pepperoni',)
('mushrooms', 'green peppers', 'extra cheese')

形參名*toppings中的星號(hào)讓Python創(chuàng)建一個(gè)名為toppings的空元組,并將收到的所有值都封裝在這個(gè)元組中蚀瘸,即使只收到一個(gè)值也是封裝在元組中狡蝶。上述例子的第一條輸出就是如此,只有一個(gè)元素的元組用小括號(hào)括起來(lái)贮勃,并在元素的后面添加一個(gè)逗號(hào)贪惹。

(1)結(jié)合使用位置實(shí)參和任意數(shù)量實(shí)參

如果要讓函數(shù)接收不同類(lèi)型的實(shí)參,必須在函數(shù)定義中將接納任意數(shù)量實(shí)參的形參放在最后寂嘉。Python先匹配位置實(shí)參和關(guān)鍵字實(shí)參奏瞬,再將余下的實(shí)參都收集到一個(gè)形參中。

def make_pizza(size, *toppings):
    print("\nMaking a " + str(size) +
            "-inch pizza with the following toppings:")
    for topping in toppings:
        print("- " + topping)

make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
# 輸出:
Making a 16-inch pizza with the following toppings:
- pepperoni

Making a 12-inch pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese
(2)使用任意數(shù)量的關(guān)鍵字實(shí)參

需要接收任意數(shù)量的實(shí)參泉孩,但預(yù)先不知道傳遞給函數(shù)的會(huì)是什么樣的信息硼端。這時(shí)候可將函數(shù)編寫(xiě)成能夠接收任意數(shù)量的鍵-值對(duì)——調(diào)用語(yǔ)句提供了多少就接收多少。

def build_profile(first, last, **user_info):
    profile = {}
    profile['first_name'] = first
    profile['last_name'] = last
    for key, value in user_info.items():
        profile[key] = value
    return profile

user_profile = build_profile('albert', 'einstein',
                             location='princeton',
                             field='physics')
print(user_profile)
# 輸出:
{'first_name': 'albert', 'last_name': 'einstein', 
'location': 'princeton', 'field': 'physics'}

形參**user_info中的兩個(gè)星號(hào)讓Python創(chuàng)建一個(gè)名為user_info的空字典寓搬,并將收到的所有名稱(chēng)-值對(duì)都封裝到這個(gè)字典中珍昨。
編寫(xiě)函數(shù)時(shí),可以以各種方式混合使用位置實(shí)參句喷、關(guān)鍵字實(shí)參和任意數(shù)量的實(shí)參镣典。

6、將函數(shù)存儲(chǔ)在模塊中

函數(shù)的優(yōu)點(diǎn)之一是唾琼,使用它們可將代碼塊與主程序分離骆撇。通過(guò)給函數(shù)指定描述性名稱(chēng),可讓主程序容易理解得多父叙。還可以將函數(shù)存儲(chǔ)在被稱(chēng)為模塊的獨(dú)立文件中神郊,再將模塊導(dǎo)入到主程序中。import語(yǔ)句允許在當(dāng)前運(yùn)行的程序文件中使用模塊中的代碼趾唱。
通過(guò)將函數(shù)存儲(chǔ)在獨(dú)立的文件中涌乳,可隱藏程序代碼的細(xì)節(jié),將重點(diǎn)放在程序的高層邏輯上甜癞。這可以在眾多不同的程序中重用函數(shù)夕晓。將函數(shù)存儲(chǔ)在獨(dú)立文件中后,可與其他程序員共享這些文件而不是整個(gè)程序悠咱。

(1)導(dǎo)入整個(gè)模塊

要讓函數(shù)是可導(dǎo)入的蒸辆,得先創(chuàng)建模塊。模塊是擴(kuò)展名為.py的文件析既,包含要導(dǎo)入到程序中的代碼躬贡。
將前面make_pizza函數(shù)放在一個(gè)名為pizza.py的文件中,然后再創(chuàng)建一個(gè)名為making_pizzas.py的文件眼坏,在文件的開(kāi)頭添加import pizza拂玻,然后在下面寫(xiě)入調(diào)用函數(shù)的語(yǔ)句運(yùn)行即可。程序運(yùn)行時(shí),import會(huì)將pizza文件中的所有函數(shù)復(fù)制到程序中檐蚜。
要調(diào)用被導(dǎo)入的模塊中的函數(shù)魄懂,可指定導(dǎo)入的模塊的名稱(chēng)pizza和函數(shù)名make_pizza(),并用句點(diǎn)分隔它們闯第。如:

pizza.make_pizza(16, 'pepperoni')

只需編寫(xiě)一條import語(yǔ)句并在其中指定模塊名市栗,就可以在程序中使用該模塊中的所有函數(shù)。

module_name.function_name()
(2)導(dǎo)入特定的函數(shù)

導(dǎo)入模塊中的特定函數(shù):

from module_name import function_name

通過(guò)用逗號(hào)分隔函數(shù)名咳短,可根據(jù)需要從模塊中導(dǎo)入任意數(shù)量的函數(shù):

from module_name import function_0, function_1, function_2

使用這種方法導(dǎo)入函數(shù)后填帽,調(diào)用函數(shù)時(shí)就不需要使用句點(diǎn)。因?yàn)橐呀?jīng)在import語(yǔ)句中顯示地導(dǎo)入了函數(shù)诲泌,所以調(diào)用時(shí)指定其名稱(chēng)即可盲赊。

(3)使用as給函數(shù)指定別名

如果要導(dǎo)入的函數(shù)的名稱(chēng)可能與程序中現(xiàn)有的名稱(chēng)沖突铣鹏,或者函數(shù)的名稱(chēng)太長(zhǎng)敷扫,可指定簡(jiǎn)短而獨(dú)一無(wú)二的別名——類(lèi)似于給函數(shù)起一個(gè)外號(hào)。若要這么做诚卸,就要在導(dǎo)入它時(shí)就要做葵第。
在import語(yǔ)句中使用關(guān)鍵字as將函數(shù)重命名為你想要的別名:

from pizza import make_pizza as mp

因?yàn)橛辛艘粋€(gè)別名,所以調(diào)用函數(shù)時(shí)可以直接用別名來(lái)調(diào)用合溺。

(4)使用as給模塊指定別名

給模塊指定別名卒密,能使代碼更簡(jiǎn)潔,而且不再關(guān)注模塊名棠赛,而專(zhuān)注于描述性的函數(shù)名哮奇,對(duì)理解代碼更好。

import module_name as mn
(5)代入模塊中的所有函數(shù)

使用星號(hào)(*)運(yùn)算符可讓Python導(dǎo)入模塊中的所有函數(shù)睛约。由于導(dǎo)入了每個(gè)函數(shù)鼎俘,可通過(guò)名稱(chēng)來(lái)調(diào)用每個(gè)函數(shù),而無(wú)需使用句點(diǎn)表示法辩涝。然而贸伐,使用并非自己編寫(xiě)的大型模塊時(shí),最好不要采用這種導(dǎo)入方法:如果模塊中有函數(shù)的名稱(chēng)與你的項(xiàng)目中使用的名稱(chēng)相同怔揩,可能導(dǎo)致意想不到的結(jié)果:Python可能遇到多個(gè)名稱(chēng)相同的函數(shù)或變量捉邢,進(jìn)而覆蓋函數(shù),而不是分別導(dǎo)入所有函數(shù)商膊。
最佳的做法是伏伐,要么只導(dǎo)入你需要使用的函數(shù),要么導(dǎo)入整個(gè)模塊并使用句點(diǎn)表示法晕拆。

from module_name import *

7秘案、函數(shù)編寫(xiě)指南

應(yīng)給函數(shù)指定描述性名稱(chēng),且只在其中使用小寫(xiě)字母和下劃線。給模塊命名時(shí)也應(yīng)遵循上述約定阱高。
每個(gè)函數(shù)都應(yīng)包含簡(jiǎn)要地闡述其功能的注釋?zhuān)撟⑨尵o跟在函數(shù)定義后面赚导,并采用文檔字符串格式。
給形參指定默認(rèn)值時(shí)赤惊,等號(hào)兩邊不要有空格吼旧。對(duì)于函數(shù)調(diào)用中的關(guān)鍵字實(shí)參,也應(yīng)遵循這種約定未舟。
如果函數(shù)的形參很多圈暗,導(dǎo)致函數(shù)定義的長(zhǎng)度超過(guò)了79字符,可在函數(shù)定義中輸入左括號(hào)后按回車(chē)鍵裕膀,并在下一行按兩次Tab鍵员串,從而將形參列表和只縮進(jìn)一層的函數(shù)體區(qū)分開(kāi)來(lái)。
如果程序或模塊包含多個(gè)函數(shù)昼扛,可使用兩個(gè)空行將相鄰的函數(shù)分開(kāi)寸齐,這樣將更容易知道前一個(gè)函數(shù)在什么地方結(jié)束,下一個(gè)函數(shù)在什么地方開(kāi)始抄谐。
所有的import語(yǔ)句都應(yīng)放在文件開(kāi)頭渺鹦,唯一例外的情形是,在文件開(kāi)頭使用了注釋來(lái)描述整個(gè)程序蛹含。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末毅厚,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子浦箱,更是在濱河造成了極大的恐慌吸耿,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酷窥,死亡現(xiàn)場(chǎng)離奇詭異咽安,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)竖幔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)板乙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人拳氢,你說(shuō)我怎么就攤上這事募逞。” “怎么了馋评?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵放接,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我留特,道長(zhǎng)纠脾,這世上最難降的妖魔是什么玛瘸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮苟蹈,結(jié)果婚禮上糊渊,老公的妹妹穿的比我還像新娘。我一直安慰自己慧脱,他們只是感情好渺绒,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著菱鸥,像睡著了一般宗兼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上氮采,一...
    開(kāi)封第一講書(shū)人閱讀 49,784評(píng)論 1 290
  • 那天殷绍,我揣著相機(jī)與錄音,去河邊找鬼鹊漠。 笑死主到,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贸呢。 我是一名探鬼主播镰烧,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼拢军,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼楞陷!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起茉唉,我...
    開(kāi)封第一講書(shū)人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤固蛾,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后度陆,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體艾凯,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年懂傀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了趾诗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蹬蚁,死狀恐怖恃泪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情犀斋,我是刑警寧澤贝乎,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站叽粹,受9級(jí)特大地震影響览效,放射性物質(zhì)發(fā)生泄漏却舀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一锤灿、第九天 我趴在偏房一處隱蔽的房頂上張望挽拔。 院中可真熱鬧,春花似錦但校、人聲如沸篱昔。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)州刽。三九已至,卻和暖如春浪箭,著一層夾襖步出監(jiān)牢的瞬間穗椅,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工奶栖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留匹表,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓宣鄙,卻偏偏與公主長(zhǎng)得像袍镀,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子冻晤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 〇苇羡、前言 本文共108張圖,流量黨請(qǐng)慎重鼻弧! 歷時(shí)1個(gè)半月设江,我把自己學(xué)習(xí)Python基礎(chǔ)知識(shí)的框架詳細(xì)梳理了一遍。 ...
    Raxxie閱讀 18,929評(píng)論 17 410
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理攘轩,服務(wù)發(fā)現(xiàn)叉存,斷路器,智...
    卡卡羅2017閱讀 134,629評(píng)論 18 139
  • 昨晚度帮,發(fā)布了微信小程序TalkBar-口才修煉卡使用指南歼捏,很多朋友留言想要提前體驗(yàn)。由于小程序認(rèn)證笨篷,以及審核的種種...
    陶唐浪跡閱讀 36,240評(píng)論 4 7
  • 咱今天就事論事,說(shuō)一說(shuō)這個(gè)寫(xiě)作的起源安聘。 開(kāi)始知道樹(shù)獺先生的活動(dòng)痰洒,是微信朋友圈看到的一條信息開(kāi)始瓢棒,當(dāng)時(shí)的活動(dòng)“這次,...
    醉含丹夢(mèng)生閱讀 223評(píng)論 0 0
  • 2017年10月178日 星期 三 晴 今天發(fā)現(xiàn)女兒最近學(xué)的數(shù)學(xué)三位數(shù)除一位數(shù)丘喻,尤其是帶余數(shù)的脯宿,掌握的很不...
    仲蕊蕊媽媽閱讀 153評(píng)論 0 0