Python編程:有關(guān)函數(shù)返回值以及最佳實(shí)踐基本指導(dǎo)原則
本篇內(nèi)容作為以函數(shù)為主題的最后一篇,來介紹一下函數(shù)返回值以及編寫函數(shù)的一些基本的最佳實(shí)踐指導(dǎo)原則。
函數(shù)輸出:返回值
函數(shù)的返回值是Python領(lǐng)先于競爭對手的東西之一。在大多數(shù)其他語言中,函數(shù)通常只允許返回一個對象,但是在Python中,你可以返回一個元組——這意味著可以返回任何你想要的東西。這個特性允許程序員編寫用其他語言編寫的軟件要困難得多,或者肯定會更加乏味。我們已經(jīng)說過,要從函數(shù)返回一些東西,我們需要使用return語句,后面跟著我們想要返回的東西。函數(shù)體中可以根據(jù)需要有多個返回語句。
另一方面,如果在函數(shù)體中我們不返回任何東西,或者我們調(diào)用一個“裸”return語句,函數(shù)將返回None。當(dāng)不需要時,這種行為是無害的,但是也允許你整些有趣的模式的,確認(rèn)Python是一種非常一致的語言。
我們說它是無害的,因?yàn)槟阌肋h(yuǎn)不會被迫收集函數(shù)調(diào)用的結(jié)果。下面將通過一個例子向你展示所說的意思:
注意,整個函數(shù)體僅由pass語句組成。正如官方文檔告訴我們的那樣,pass是一個空操作,因?yàn)楫?dāng)它被執(zhí)行時,什么也不會發(fā)生。當(dāng)語法上需要語句但不需要執(zhí)行代碼時,它作為占位符非常有用。在其他語言中,我們可能只需要用一對花括號({})來表示,這定義了一個空作用域;但在Python中,作用域是由縮進(jìn)代碼定義的,因此像pass這樣的語句是必要的。
還要注意,func()的第一個調(diào)用返回一個沒有接收的值(None)。正如我們前面提到的,接收函數(shù)調(diào)用的返回值不是必須的。
這很好,但不是很有趣,我們寫一個有趣的函數(shù)怎么樣?還記得我們討論過階乘函數(shù)。讓我們在這里編寫我們自己的實(shí)現(xiàn)(為了簡單起見,我們假設(shè)函數(shù)總是用適當(dāng)?shù)闹嫡_調(diào)用,所以我們不需要檢查輸入?yún)?shù)):
注意,我們有兩個返回點(diǎn)。如果n是0或1,則返回1。否則,我們執(zhí)行所需的計(jì)算并返回結(jié)果。
提示:在Python中,通常使用in操作符來進(jìn)行成員檢查,就像我們在前面的例子中所做的那樣,而不是更冗長的檢查:
if n == 0 or n == 1:
…
現(xiàn)在再來試著把這個函數(shù)寫得更簡潔一點(diǎn):
這個簡單的示例展示了Python是如何既優(yōu)雅又簡潔的。即使我們從未見過reduce()或mul(),這個實(shí)現(xiàn)也是可讀的。如果你不能看懂或理解它,抽出幾分鐘來做一些Python文檔研究,直到你清楚它的行為。能夠在文檔中查找函數(shù)并理解由其他人編寫的代碼是每個開發(fā)人員都需要能夠執(zhí)行的任務(wù),因此將其作為一個挑戰(zhàn)。
提示:學(xué)會查看Python自帶幫助,請確保查找help()函數(shù),這在使用控制臺進(jìn)行探索時非常有用。
返回多個值
正如我們前面提到的,與大多數(shù)其他語言不同,Python非常容易從一個函數(shù)返回多個對象。這個特性帶來了無限的可能性,并允許你以一種難以用其他語言再現(xiàn)的風(fēng)格進(jìn)行編碼。我們的思維會受到我們使用的工具的限制。因此,當(dāng)Python給予你比其他語言更多的自由時,它就是在增強(qiáng)你的創(chuàng)造性能力。
返回多個值非常簡單:只需使用元組(顯式或隱式)。讓我們看一個模仿divmod()內(nèi)置函數(shù)的簡單例子:
我們可以將前面代碼中粗體部分包裝在括號中,使其成為顯式元組,但沒有必要這樣做。上面的函數(shù)同時返回除法的結(jié)果和余數(shù)。
有關(guān)函數(shù)的有益建議
在編寫函數(shù)時,遵循一些最佳實(shí)踐指導(dǎo)原則是非常有用的,這樣才能很好地編寫函數(shù)。我們來看一看這些指導(dǎo)原則,以助益你更好的理解和應(yīng)用函數(shù)。
1)函數(shù)應(yīng)只做一件事
做一件事的函數(shù)很容易用一句話來描述。執(zhí)行多項(xiàng)任務(wù)的函數(shù)可以重構(gòu)拆分為執(zhí)行一項(xiàng)任務(wù)的更小函數(shù)。這些較小的函數(shù)通常更容易閱讀和理解。
2)函數(shù)應(yīng)是很小的
它們越小,測試和編寫它們就越容易,這樣它們也就更專注于只做一件事。
3)輸入?yún)?shù)越少越好
接受大量參數(shù)的函數(shù)很快就變得難以管理(以及其他問題)。當(dāng)需更多的輸入?yún)?shù)時,酌情考慮,如重構(gòu)為類對象或其它復(fù)合型數(shù)據(jù)。
4)函數(shù)的返回值應(yīng)該一致
返回False和返回None不是一回事,即使在布爾上下文中,它們的值都是False。False表示我們有信息(即False),而None表示沒有信息。盡可能編寫以一致的方式返回的函數(shù),無論其邏輯中發(fā)生了什么。
5)函數(shù)不應(yīng)該有副作用
換句話說,函數(shù)不應(yīng)該影響調(diào)用它們的值。這可能是目前最難理解的一條實(shí)踐性原則,所以這里給出一個使用列表的示例。在下面的代碼中,注意如何不使用sorted()函數(shù)對numbers進(jìn)行排序,該函數(shù)實(shí)際上返回的是已排序的數(shù)字副本。相反,list.sort()方法作用于numbers對象本身,這很好,因?yàn)樗且粋€方法(屬于對象的函數(shù),因此有權(quán)修改它):
所以,遵循以上這些常規(guī)的基本指導(dǎo)原則,將有益于你寫出更好的函數(shù),為你實(shí)現(xiàn)更好的服務(wù)。
本文小結(jié)
到此關(guān)于Python函數(shù)的主體性知識就介紹完了——函數(shù)定義語法、輸入?yún)?shù)定義以及相關(guān)規(guī)則、返回值實(shí)現(xiàn)和多返回值等,并簡單總結(jié)了基于最佳實(shí)踐的一些有益基本指導(dǎo)原則。請多加練習(xí)和體會,以便更好的理解和掌握作為Python的核心特性之一的函數(shù)。