重溫Python的知識結(jié)構(gòu)
- 程序由模塊組成。
- 模塊包含語句。
- 語句包含表達式。
- 表達式創(chuàng)建并處理對象。
從基礎(chǔ)上看,Python編寫的程序?qū)嶋H上時由語句和表達式構(gòu)成的。表達式用于處理對象,并被嵌入到語句中。語句使用并引導(dǎo)表達式處理我們前幾章所學(xué)的對象。
語句可以創(chuàng)建對象。
Python的語句
下表總結(jié)了Python的語句集。其中,有些語句已經(jīng)在前面的章節(jié)中使用到。
| 語句 | 功能 | 示例 |
|---|---|---|
| 賦值 | 創(chuàng)建引用值 | a, b = 'good', 'bad' |
| 調(diào)用與其他表達式 | 運行函數(shù) | log.write("spam, ham") |
print調(diào)用 |
打印對象 | print('The Killer', joke) |
if/elif/else |
選擇動作 | if "python" in text: print(text) |
for |
序列迭代 | for x in mylist: print(text) |
while |
通用循環(huán) | while X > Y: print('hello') |
pass |
空占位符 | while True: pass |
break |
循環(huán)推出 | while True: if exittest(): break |
continue |
循環(huán)繼續(xù) | while True: if skiptest(): continue |
def |
函數(shù)與方法 | def f(a, b, c=1, *d): print(a+b+c+d[0]) |
return |
函數(shù)結(jié)果 | def f(a, b, c=1, *d): return a+b+c+d[0] |
yield |
生成器函數(shù) | def gen(n): for i in n: yield i*2 |
global |
命名空間 | x = 'old'def function(): global x, y; x = 'new' |
nonlocal |
命名空間 | def outer(): x = 'old'def function(): global x, y; x = 'new' |
import |
獲取模塊 | import sys |
from |
獲取屬性 | from sys import stdin |
class |
構(gòu)建對象 | class Subclass(Superclass): staticData = [] def method(self): pass |
try/except/finally |
捕捉異常 | try: action()except: print("action error") |
raise |
觸發(fā)異常 | raise EndSearch(location) |
assert |
調(diào)試檢查 | assert X > Y, 'X too small' |
with/as |
上下文管理器(3.X,2.6+) | with open('data') as myfile: process(myfile) |
del |
刪除引用 | del data[k]del data[i:j]del obj.attrdel variable |
說明:
- 賦值語句有多種形式:基本的、序列的、擴展的。
print在Python 3.X是一個內(nèi)置函數(shù)調(diào)用,在Python 2.X是一個語句。yield在Python 3.X也是一個表達式,而不是語句。
版本2.X的特性:
nonlocal不可用。exec是一個語句,有特定的語法。try/except和try/finally合并(2.5)。with/as需要導(dǎo)入模塊__future__中的with_statement。
兩種不同的if
這里著重說明Python的語法與C/C++的語法的不同。以if為例,在C/C++是這么寫的:
if (x > y){
x = 1;
y = 2;
}
Python是這么寫的:
if x > y:
x = 1
y = 2
看上去,Python更簡潔。
Python增加的元素
Python增加了冒號:,所有的Python復(fù)合語句(即內(nèi)嵌了其他語句的語句)都是如此,即首行以冒號結(jié)尾,下一行嵌套的代碼縮進:
Header line:
Nested statement block
Python刪除的元素
括號是可選的
首先是語句第一行的括號:
if (x > y){
在Python中,可以不用括號。雖然用括號不會報錯,但不用括號更接近Python風(fēng)格。
行終止就是語句終止
在C/C++中,語句以分號;終止。一般情況下,Python的語句以一行的結(jié)束為結(jié)束而不需要分號。也就是說,x = 1 會被視為一個語句。但是,如果用一些特殊手段,Python的語句會變?yōu)槎嘈小?/p>
縮進的結(jié)束就是代碼塊的結(jié)束
在C/C++中,代碼塊以左大括號{開始,以右大括號}結(jié)束。在Python中,代碼塊以開始縮進為開始,以結(jié)束縮進為結(jié)束。這里,代碼塊就是第2-3行。縮進就是:左側(cè)留空白。
if x > y:
x = 1
y = 2
a = 1
為什么采用縮進語法
根據(jù)邏輯結(jié)構(gòu)將代碼對齊是使程序具有可讀性的重要步驟。實際上,編寫任何語言的代碼都需要通過縮進來提高可讀性,成熟的IDE也支持自動縮進。
經(jīng)驗法則:不應(yīng)該在同一段Python代碼中混合使用制表符\t和空格,否則會引發(fā)錯誤。
幾種特殊情況
在Python語法模型中:
-
一行的結(jié)束就終止了該行語句(沒有分號)。
-
嵌套語句通過它們的縮進,來劃分代碼塊(沒有大括號)。
語法規(guī)則的特殊情況
一行擠進多條語句,此時這些語句由分號隔離的情況:
>>> a = 1; b = 2; print(a + b)
3
只有當擺到一起的語句本身不是復(fù)合語句時才這么做,如果有if、while等語句最好單獨開一行。
一條語句的范圍橫跨多行的情形。實現(xiàn)這一操作只需要用一對括號把語句括起來。任何括在這些符號里的代碼都可以跨越好幾行,直到Python遇到閉合括號的那一行。
mylist = [1111,
2222,
3333]
這里程序被括在一對方括號里,因此Python接著運行下一行,直到遇見閉合的方括號為止。大括號中的字典集合、中括號的序列、小括號的元組都可以這么用。
括號可以包含一切,包括表達式和復(fù)合語句:
X = (A + B +
C + D)
if (A == 1 and
B == 2 and
C == 3):
print('spam' * 3)
還有一種方法能夠跨越數(shù)行——用反斜線。
X = A + B + \
C + D
這種方法容易引發(fā)錯誤(反斜線不能有空格),因此不推薦。
代碼塊規(guī)則的特殊情況
復(fù)合語句的主體如果只有一行,可以出現(xiàn)在Python的首行冒號之后:
if x > y: print(x)
當然,這種情況只適用于復(fù)合語句本身只包含一個簡單語句的情況。也可以用多個語句用分號擠進一行(但不推薦)。
簡短示例:交互式循環(huán)
一個簡單的交互式循環(huán)
假設(shè)有人要求寫一個程序,要求在控制窗口與用戶交互。準確的說,要求用戶鍵盤輸入數(shù)據(jù)的循環(huán)并打印每次讀取的結(jié)果。我們需要寫一個標準的“讀取/計算/打印”的循環(huán)程序。
這種程序類似于:
while True:
reply = input('Enter text:')
if reply == 'stop': break
print(reply.upper())
以下是這段代碼的解釋:
- 這段代碼利用率Python的
while循環(huán),它后面跟著一個表達式,可能是真或者是假,冒號后面是當表達式為真時,執(zhí)行的復(fù)合語句。當復(fù)合語句執(zhí)行完畢,在回到while循環(huán)重新判斷表達式的真假。 input用于控制臺輸入,它的參數(shù)是一個字符串,當執(zhí)行到這一語句,input輸出這個字符串,讀取用戶輸入的內(nèi)容并返回用戶輸入的內(nèi)容。- 單行的
if在這里出現(xiàn)。 break語句會跳出當前的循環(huán)。
這段代碼的功能是:從用戶讀取一行輸入,并轉(zhuǎn)換成大寫字母打印,直到用戶輸入stop為止。注意到,while首行下面的三行代碼都有同樣程度的縮進,這意味著它們都是與while相關(guān)聯(lián)、重復(fù)的代碼塊。
對用戶輸入做數(shù)學(xué)運算
以剛才的交互式循環(huán)為基礎(chǔ),我們要做一些數(shù)學(xué)運算。比如,每一次循環(huán),輸入一個數(shù),返回這個數(shù)的平方:
while True:
reply = input('Enter text:')
if reply == 'stop': break
print(int(reply) ** 2)
print('Bye')
用戶輸入的數(shù)是以字符串類型表示的,但是只有數(shù)值類型才能進行平方運算。因此我們要通過int函數(shù)把字符串轉(zhuǎn)換為整數(shù)。
這里的程序在末尾加了輸出'Bye'的信息。由于它沒有縮進,故不是循環(huán)體的一部分。也就是說,跳出循環(huán)后這個語句才會執(zhí)行。
通過測試輸入數(shù)據(jù)來處理錯誤
對應(yīng)剛才的程序而言,如果我們輸入了處數(shù)字和stop以外的內(nèi)容,會出現(xiàn)錯誤。
Enter text:123
15129
Enter text:?
Traceback (most recent call last):
File "<.py文件的絕對路徑>", line 4, in <module>
print(int(reply) ** 2)
ValueError: invalid literal for int() with base 10: '?'
這是因為我們剛才忽略了“亂輸入”的情況。我們可以用字符串對象的isdigit方法檢查字符串是否為一個數(shù)字:
while True:
reply = input('Enter text:')
if reply == 'stop':
break
elif not reply.isdigit():
print('Bad!' * 8)
else:
print(int(reply) ** 2)
print('Bye')
這里,if、elif、else是同一個語句的組成部分,Python執(zhí)行語句時會從上到下檢測冒號前面的表達式是否為真,如果為真則執(zhí)行代碼塊,否則跳到代碼塊下一行。接著,整個if區(qū)塊都在while循環(huán)的一部分。
運行時,如果輸入的既不是數(shù)字,也不是stop,那么程序會在錯誤發(fā)生前捕捉它,并打印錯誤消息,否則其行為與之前的程序不變。
用try處理錯誤
try也可以捕捉錯誤并做出反應(yīng)。
while True:
reply = input('Enter text:')
if reply == 'stop': break
try:
num = int(reply)
except:
print('Bad!' * 8)
else:
print(num ** 2)
print('Bye!')
try是一種復(fù)合語句,其組成是:try關(guān)鍵字后面跟著一個代碼塊,再跟著一個提供異常處理代碼的except部分、以及沒有引發(fā)異常時執(zhí)行的else部分。Python首先執(zhí)行try后面的代碼塊,如果有異常,則執(zhí)行except的代碼塊,否則執(zhí)行else的代碼塊。
對浮點數(shù)的支持
如果我們不只是要計算整數(shù)的平方,我們可以用float()方法把字符串轉(zhuǎn)化為浮點數(shù)。但是,此時我們不能用isdigit()函數(shù)了,也就是第一種方法不行。
嵌套三層深的代碼
我們可以進一步改進。比如,我們根據(jù)輸入的大小,決定是否打印結(jié)果。
while True:
reply = input('Enter text:')
if reply == 'stop':
break
elif not reply.isdigit():
print('Bad!' * 8)
else:
num = int(reply)
if num < 20:
print('low')
else:
print(int(reply) ** 2)
print('Bye')
這個版本把一個if語句嵌入另一條if語句的else部分。當出現(xiàn)這樣嵌套的情形時,我們只需要再向右縮進即可。
浙公網(wǎng)安備 33010602011771號