
Python裝飾器原理與簡(jiǎn)單用法實(shí)例分析
Python 解釋器在其最簡(jiǎn)單的級(jí)別,以類似的方式操作,即從程序的頂端開始,然后一行一行地順序執(zhí)行程序語句。例如,清單 1 展示了幾個(gè)簡(jiǎn)單的語句。當(dāng)把它們鍵入 Python 解釋器中(或者將它們保存在一個(gè)文件中,并作為一個(gè) Python 程序來執(zhí)行)時(shí),讀取語句的順序是從左到右。 當(dāng)讀到一個(gè)行結(jié)束符(比如換行符)時(shí),Python 解釋器就前進(jìn)到下一行并繼續(xù),直到?jīng)]有了代碼行。
清單 1. 一個(gè)簡(jiǎn)單的 Python 程序
>>> i = 1
>>> type(i)
<type 'int'>
>>> l = [0, 1, 2, 3, 4]
>>> l * i
[0, 1, 2, 3, 4]
在本例中,語句以簡(jiǎn)單的順序一個(gè)接一個(gè)。但是情況并不總是線性的??紤]一個(gè)個(gè)人的例子。您今天早上醒來,聽了交通或天氣報(bào)告(或者兩者都聽了)。根據(jù)交通報(bào)告,您可能選擇了一條不同的上班路線;或者類似地,根據(jù)天氣報(bào)告,您為周末計(jì)劃了不同的活動(dòng)。您的對(duì)策并不簡(jiǎn)單;根據(jù)您所獲得的信息,生活的自然順序迂回而曲折。
Python 像大多數(shù)編程語言一樣,通過使用流控制語句,也可以以這種方式操作。在 Python 中,有 3 種基本的流控制語句:
if 語句,它基于測(cè)試表達(dá)式的結(jié)果執(zhí)行一個(gè)特定的語句塊。
while 循環(huán),它當(dāng)一個(gè)測(cè)試表達(dá)式為 true 時(shí)執(zhí)行一個(gè)語句塊。
for 循環(huán),它對(duì)一個(gè)語句塊執(zhí)行一定次數(shù)。
這個(gè)列表相當(dāng)簡(jiǎn)單,并且您可能從其他編程語言認(rèn)識(shí)了這些流控制語句。但是您可能在想,語句塊 是什么意思呢。在清單 1 中,您看到了幾個(gè)簡(jiǎn)單的語句,包括一個(gè)變量初始化、一個(gè)方法調(diào)用(type 方法)和一個(gè)乘法操作。這些語句執(zhí)行一個(gè)簡(jiǎn)單的操作,因此把它們叫做簡(jiǎn)單語句。
Python 也具有復(fù)合語句,即相關(guān)語句形成的語句組,其中包括簡(jiǎn)單和(可能)附加的復(fù)雜語句。例如,根據(jù)表達(dá)式的值(對(duì)個(gè)人來說,可能是對(duì)“今天的天氣晴朗嗎”之類問題的答案),一個(gè)復(fù)合語句可能執(zhí)行不同的操作或者對(duì)一個(gè)操作重復(fù)多次。這一描述似乎有些類似于前一段的流控制描述。當(dāng)然應(yīng)該類似,因?yàn)榱骺刂普Z句就是復(fù)合語句。
一個(gè)復(fù)合語句包括一個(gè)流控制指令,后跟一個(gè)冒號(hào)(:),然后再是一個(gè)程序語句塊。語句塊由一個(gè)或多個(gè)簡(jiǎn)單語句和復(fù)合語句組成。清單 2 中提供了一個(gè)簡(jiǎn)單的偽代碼例子。
清單 2. 一個(gè)偽代碼例子展示了簡(jiǎn)單語句和復(fù)雜語句
simple statement one
compound statement one:
simple statement two
simple statement three
compound statement two:
simple statement four
simple statement five
該語法看起來既熟悉又陌生,并且兩種感覺來自相同的事情:縮進(jìn)。在列大綱或步驟時(shí),您可能會(huì)使用不同級(jí)別的縮進(jìn)來分隔每一項(xiàng),使得列出來的東西更加清晰可讀。Python 遵循這一模型,使用縮進(jìn)來分隔代碼塊與程序的其余部分。其他編程語言使用特殊的字符來區(qū)分代碼塊,比如基于 C 的語言中的花括號(hào)({ 和 })。這些其他語言也鼓勵(lì)程序員使用縮進(jìn),以改善程序的可讀性。
另一方面,Python 需要縮進(jìn)以指示代碼塊。如果沒有正確地縮進(jìn),Python 解釋器會(huì)拋出異常。可以使用制表符來標(biāo)記縮進(jìn),但是一般推薦使用空格。(為了一致性,我總是使用 4 個(gè)空格來縮進(jìn)代碼塊。)理由很簡(jiǎn)單:空格字符只有一種解釋方式。另一方面,制表符可以有不同的解釋方式,根據(jù)所使用的平臺(tái)或工具,可以解釋為 2 個(gè)、4 個(gè)、6 個(gè)甚至 8 個(gè)空格。
增強(qiáng)程序可讀性
縮進(jìn)要求可能是 Python 的一個(gè)基本指導(dǎo)原則 —— Python 程序應(yīng)該易于讀和理解 —— 的最佳例子。但是這就跟工具一樣,頑固分子也可能會(huì)編寫晦澀的 Python 代碼。例如,螺絲起子是用來起螺絲的,但是有時(shí)您也可能用來打開油漆蓋子。
兩個(gè)其他特性有助于編寫易讀的 Python 程序,并且這兩者都遵循前面所用的書的比喻。首先,書中的行不會(huì)延伸到頁面外面,都有固定的長(zhǎng)度。其次,書中的行不是以特殊符號(hào)(比如分號(hào))結(jié)束。這兩個(gè)特性都貫穿于編寫 Python 程序的過程中。
如果某個(gè)程序行太長(zhǎng),可以在文件中的下一物理行繼續(xù)這一行。沒有硬性規(guī)定一個(gè)代碼行應(yīng)該多長(zhǎng)。但是一般限制為 80 個(gè)字符,這容易適合大多數(shù)顯示器的一個(gè)打印頁面。有幾種方式來擴(kuò)展超過一行的代碼語句:
三引號(hào)字符串可以擴(kuò)展到多個(gè)行。
括號(hào)中的表達(dá)式可以擴(kuò)展到多個(gè)行。
可以使用繼續(xù)字符(\)來在多行分割語句。
在 Python 中,不需要使用特殊字符(或符號(hào))來指示語句的結(jié)束。這與有些語言不同。例如,基于 C 的語言使用分號(hào)(;)來指示代碼行的結(jié)束。然而,有時(shí)候需要在一行放多個(gè)程序語句,例如初始化變量時(shí)。在這樣的情況下,可以使用分號(hào)來分隔單個(gè)語句。
清單 3 中演示了這兩種技術(shù)。
清單 3. 演示 Python 的可讀性技術(shù)
>>> i1 = 10 ; i2 = 20 ; i3 = 30
>>>
>>> b = ((i1 < 20) and
... (i2 < 30) and
... (i3 < 40))
>>> b
True
>>>
>>> b = (i1 < 20) and \
... (i2 < 30) and \
... (i3 < 40)
>>>
>>> b
True
注意清單 3 中擴(kuò)展到多個(gè)行的程序語句是如何縮進(jìn)以改善可讀性的。在本例中,縮進(jìn)不是強(qiáng)制性的,就跟一個(gè)復(fù)合語句一樣。但是正如您所見,縮進(jìn)改善了程序的外觀,因而強(qiáng)烈推薦進(jìn)行縮進(jìn)。
if 語句
最簡(jiǎn)單的流控制語句是 if 語句,它的基本語法在清單 4 中的偽代碼中演示了。if 語句在一個(gè)布爾表達(dá)式計(jì)算為 True 時(shí)執(zhí)行一個(gè)程序語句塊。if 語句支持一個(gè)可選的 else 子句,指示當(dāng)布爾表達(dá)式計(jì)算為 False 時(shí)應(yīng)該處理的程序語句塊。
清單 4. if 語句的基本語法
if(expression one):
# Action to take if expression one evaluates True
else:
# Action to take if all expression one evaluates False
如果您使用過其他編程語言,那么該語法看起來可能既熟悉又陌生。相似之處在于 if 語句的一般格式、名稱、用于確定如何分支語句執(zhí)行流的表達(dá)式的計(jì)算,以及用于處理當(dāng)表達(dá)式計(jì)算為 False 時(shí)的情況的 else 子句。但是有兩個(gè)方面是完全特定于 Python 的:帶有冒號(hào)字符的 if 和 else 語句的終止,以及 if 和 else 塊中語句的縮進(jìn)。正如所提到的,這兩個(gè)特征是 Python 中流控制語句所必需的。
在清單 5 中,一個(gè)簡(jiǎn)單的 if/else 條件測(cè)試一個(gè)給定的數(shù)字是奇數(shù)還是偶數(shù),并打印出結(jié)果。
清單 5. 一個(gè)簡(jiǎn)單的 if 語句例子
>>> i = 8
>>> if(i % 2):
... print "Odd Number"
... else:
... print "Even Number"
...
Even Number
一個(gè)似乎有些混亂的地方是 if 語句后面每一行前面的三個(gè)點(diǎn)(...)。當(dāng)鍵入 if 語句和終止的冒號(hào),并按鍵盤上的回車鍵時(shí),Python 解釋器就知道您輸入了一個(gè)復(fù)合語句。因此,它就將提示符從三個(gè)大于符號(hào)(>>>)改為三個(gè)點(diǎn)(...)。因?yàn)?Python 需要縮進(jìn)以錯(cuò)開當(dāng)表達(dá)式計(jì)算為 True 或 False 時(shí)應(yīng)該執(zhí)行的語句塊,所以兩個(gè) print 語句都縮進(jìn)了 4 個(gè)空格。
if 語句(以及本文后面討論的 elif 子句和 while 循環(huán))中的表達(dá)式可以很復(fù)雜。它可以包括多個(gè)使用 Python 中支持的不同關(guān)系運(yùn)算符的子表達(dá)式。而子表達(dá)式又可使用 and、or 和 not 邏輯運(yùn)算符組合起來。本系列的第一篇文章“探索 Python,第 1 部分:Python 的內(nèi)置數(shù)值類型”,包含更多關(guān)于布爾表達(dá)式和 Python 中不同關(guān)系和邏輯運(yùn)算符的信息。
至此,已經(jīng)看到了 if 語句可以如何用于根據(jù)一個(gè)特定布爾表達(dá)式的值,來執(zhí)行兩個(gè)程序語句塊中的其中一個(gè)。然而在有些情況下,可能需要更多的選擇。幸運(yùn)的是,Python 提供了 if 語句的一個(gè)簡(jiǎn)單擴(kuò)展。提供的解決方案非常簡(jiǎn)單:給 else 子句添加一個(gè)額外的 if 語句。結(jié)果是一個(gè) else if 語句,簡(jiǎn)寫為 elif,如清單 6 所示。
清單 6. 使用 elif 語句
>>> i = -8
>>> if(i > 0):
... print "Positive Integer"
... elif(i < 0):
... print "Negative Integer"
... else:
... print "Zero"
...
Negative Integer
本例只包含一個(gè) elif 語句,而實(shí)際中可根據(jù)程序需要包含任意多個(gè)。盡管它不是最優(yōu)的解決方案,但是多個(gè) elif 語句可以用于模擬其他一些語言中的 switch case 語句。
while 循環(huán)
Python 中的第二種流控制語句是 while 循環(huán),它在一個(gè)表達(dá)式計(jì)算為 True 時(shí)執(zhí)行一個(gè)程序語句塊。while 循環(huán)與 if 語句一樣,支持一個(gè)可選的 else 子句,其中包含一個(gè)當(dāng)表達(dá)式計(jì)算為 False 時(shí)執(zhí)行的程序語句塊。但是對(duì)于 while 循環(huán),這意味著在循環(huán)終止后,else 子句中的代碼被執(zhí)行一次(參見清單 7 中的偽代碼)。
清單 7. while 循環(huán)的偽代碼
while (expression):
# statements to execute while loop expression is True
else:
# statements to execute when loop expression is False
理解了 if 語句之后,while 循環(huán)理解起來就相當(dāng)簡(jiǎn)單了。但是一定要知道,循環(huán)一直要執(zhí)行到表達(dá)式計(jì)算為 False。這意味著循環(huán)體中執(zhí)行的程序語句必須要改變表達(dá)式的值,否則循環(huán)將無法結(jié)束。如清單 8 所示。
清單 8. while 循環(huán)的一個(gè)簡(jiǎn)單例子
>>> i = 0 ; x = 10
>>> while(x > 0):
... i+=1 ; x -= 1
... else:
... print i, x
...
10 0
該例演示了幾件事情。首先,它在一行中組合了變量初始化和變量修改:在本例中是 i 和 x 變量。其次,分別使用縮寫形式的運(yùn)算符 += 和 -= 來遞增 i 的值和遞減 x 的值。在本例中,循環(huán)開始時(shí) x 的值為 10。每通過一次循環(huán),x 的值就遞減 1。最后,x 的值為 0,此時(shí)循環(huán)退出,并執(zhí)行 else 子句中的代碼,打印出兩個(gè)變量的值。
while 循環(huán)(與本文后面介紹的 for 循環(huán)一樣)支持三種附加語句:
continue
break
pass
continue 和 break 語句分別用于在 while 循環(huán)中繼續(xù)下一次循環(huán)或中斷循環(huán)。這兩個(gè)語句通常放在 if 語句體中,以便由一個(gè)特殊的條件觸發(fā) continue 或 break 操作。break 語句的一個(gè)特殊特性是,它完全中斷循環(huán),并跳轉(zhuǎn)到循環(huán)下面的任一個(gè) else 子句。
pass 語句什么都不做。它用作一個(gè)占位符,即在需要一個(gè)語句,但是程序邏輯不需要操作時(shí)使用。清單 9 中演示了這三種語句。
清單 9. 使用 continue、break 和 pass 語句
>>> i = 1
>>> while(i < 1000):
... i *= 5
... if(i % 25):
... continue
... if not (i % 125):
... break
... if not (i % 1000):
... pass
... else:
... print i
...
>>> print i
125
這個(gè)虛構(gòu)的例子一直循環(huán)到變量 i 大于或等于 1,000。在循環(huán)中,將 i 乘以 5,然后測(cè)試 i 是否被 25 整除。記住,您只在表達(dá)式為 True 時(shí)執(zhí)行 if 語句體。該表達(dá)式在當(dāng)變量 i 不能被 25 整除時(shí)計(jì)算為 True。(在 Python 表達(dá)式中,非零數(shù)被計(jì)算為布爾值 True。)
循環(huán)體中的下一個(gè)語句是第二個(gè) if 語句,它測(cè)試變量 i 是否能被 125 整除,但是該表達(dá)式前面加了一個(gè) not 運(yùn)算符。因此,當(dāng)變量 i 的值能被 125 整除時(shí)執(zhí)行第二個(gè) if 語句體。此時(shí),break 語句導(dǎo)致程序執(zhí)行中斷 while 循環(huán),跳轉(zhuǎn)到 else 子句。
最后一個(gè) if 語句永遠(yuǎn)不會(huì)執(zhí)行,只是用于演示如何在程序中編寫 pass 語句。在后續(xù)文章中,將會(huì)介紹 pass 語句更相關(guān)的一些情況。
通過跟蹤程序的邏輯流可以看到,第一次通過循環(huán)后,變量 i 的值變?yōu)?5。第一個(gè) if 語句計(jì)算為 True,因?yàn)?5 不能被 25 整除。這就會(huì)第二次進(jìn)入 while 循環(huán),這次變量 i 變成了 25?,F(xiàn)在第一個(gè) if 語句計(jì)算為 False,因?yàn)?25 能被 25 整除。第二個(gè)和第三個(gè) if 語句也計(jì)算為 False,意味著第三次進(jìn)入循環(huán)。這次變量 i 變成了 125,并且第一個(gè) if 語句計(jì)算為 False。
但是第二個(gè) if 語句計(jì)算為 True,因?yàn)樽兞?i 能被 125 整除(并且 not 運(yùn)算符將結(jié)果 0 轉(zhuǎn)換成布爾值 True)。這導(dǎo)致執(zhí)行 break 語句,中斷循環(huán)。else 子句永遠(yuǎn)不被執(zhí)行,所以直到顯式使用 print 語句之前不會(huì)輸出任何東西。
for 循環(huán)
Python 中的 for 循環(huán)很特殊,與 Python 編程語言中內(nèi)置的容器數(shù)據(jù)類型緊密相關(guān)。當(dāng)您在現(xiàn)實(shí)生活中有一個(gè)容器對(duì)象(比如書包)時(shí),您通常想要看它所包含的東西。在編寫 Python 程序時(shí)也是這樣的。當(dāng)需要對(duì)某件事情做一定的次數(shù)時(shí)(就像針對(duì)容器中的每一項(xiàng)一樣),可使用 for 循環(huán)。清單 10 中的偽代碼格式演示了 for 循環(huán)。
清單 10. for 循環(huán)的偽代碼
for item in container:
# action to repeat for each item in the container
else:
# action to take once we have finished the loop.
由于 Python 容器類型的豐富特性,for 循環(huán)非常強(qiáng)大。本質(zhì)上,for 循環(huán)涉及到一個(gè)迭代器(iterator),用于在集合中逐項(xiàng)移動(dòng)。本系列的下一篇文章將更加詳細(xì)地介紹 for 循環(huán),以及如何正確地將它與不同容器類型一起使用。
控制流
本文介紹了三種 Python 程序語句:if 語句、while 循環(huán)和 for 循環(huán)。這三種語句通過選擇執(zhí)行哪些語句,或者通過多次執(zhí)行一組語句,讓您可以改變程序流。在后續(xù)文章中將大量用到這些語句。復(fù)合語句的特性引入了 Python 程序中的適當(dāng)縮進(jìn)特性,這使得 Python 程序易于讀和理解。
數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼
若不方便掃碼,搜微信號(hào):CDAshujufenxi
SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實(shí)戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢效率:打破 “拆分必慢” 的認(rèn)知誤區(qū) 在 MySQL 數(shù)據(jù)庫管理中,“大表” 始終是性能優(yōu)化繞不開的話題。 ...
2025-09-18CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-18DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動(dòng)態(tài)隨機(jī)一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價(jià)值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲(chǔ)的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實(shí)戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫)處理 Excel 數(shù)據(jù)時(shí),“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗(yàn)與 t 檢驗(yàn):差異、適用場(chǎng)景與實(shí)踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計(jì)學(xué)領(lǐng)域,假設(shè)檢驗(yàn)是驗(yàn)證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲(chǔ)的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計(jì)劃中 rows 數(shù)量的準(zhǔn)確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計(jì)劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對(duì)象的 text 與 content:區(qū)別、場(chǎng)景與實(shí)踐指南 在 Python 進(jìn)行 HTTP 網(wǎng)絡(luò)請(qǐng)求開發(fā)時(shí)(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價(jià)值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請(qǐng)求工具對(duì)比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請(qǐng)求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長(zhǎng)浮點(diǎn)數(shù)據(jù)的科學(xué)計(jì)數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長(zhǎng)浮點(diǎn)數(shù)據(jù)時(shí)的科學(xué)計(jì)數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價(jià)值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運(yùn)營(yíng)問題、提升執(zhí)行效率的核心手段,其價(jià)值 ...
2025-09-12用 SQL 驗(yàn)證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實(shí)戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計(jì)” 與 “用戶體驗(yàn) ...
2025-09-11塔吉特百貨孕婦營(yíng)銷案例:數(shù)據(jù)驅(qū)動(dòng)下的精準(zhǔn)零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當(dāng)下,精準(zhǔn)營(yíng)銷成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務(wù)數(shù)據(jù)分析:概念辨析與協(xié)同價(jià)值 在數(shù)據(jù)驅(qū)動(dòng)決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務(wù)數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類分析:從操作實(shí)踐到業(yè)務(wù)價(jià)值挖掘 在數(shù)據(jù)分析場(chǎng)景中,聚類分析作為 “無監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計(jì)模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價(jià)值導(dǎo)向 統(tǒng)計(jì)模型作為數(shù)據(jù)分析的核心工具,并非簡(jiǎn)單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10