[Python]程序結構與控制流

1. 條件語句

if、else與elif語句用於控制條件代碼的執行。條件語句的一般格式如下:

if expression:
    statements
elif expression:
    statements
elif expression:
    statements
...
else:
    statements

如果不需要執行任何操作,可以省略條件語句的else和elif子句。如果特定子句下不存在要執行的語句,可以使用pass語句。
 

2. 循環與迭代

可以使用for和while語句實現循環,例如:

while expression:
    statements

for i in s:
    statements

while語句反覆執行循環體中的語句。直到相關表達式求值爲false。for語句迭代s中的所有元素,直到再元可用元素。for語句僅適用於可支持迭代的對象。
如果迭代中使用的元素是元素大小完全一致的序列,每次迭代時,會把相應序列的各個元素賦值給變量x、y和z。儘管使用這行代碼時s大多爲元組序列,但s中的各項可以爲任意類型的序列,包括列表、生成器和字符串。
循環時,除了數據值之外,有時還需要跟蹤數字索引,可以使用內置函數enumerate(),例如:

for i,x in enumerate(s):
    statements

enumerate(s)創建了一個迭代器,其返回值就是一個元組的序列(0, s[0])、(1, s[1])、(2, s[2])等等。關於迭代的另一個常見問題是並行迭代兩個以上的序列,可以使用zip()函數,例如:

for x, y in zip(s, t):
    statements

zip(s, t)將序列s和t組合成一個元組序列(s[0], t[0])、(s[1], t[1])、(s[2], t[2])等等。如果s和t的長度不等,則用完長度最短的索引爲止。
使用break語句可從循環中跳出,例如:

for line in open("foo.txt"):
    stripped = line.strip()
    if not stripped:
        break # 遇到空行,停止讀取

使用continue語句可以跳到循環的下一次迭代,例如:

for line in open("foo.txt"):
    stripped = line.strip()
    if not stripped:
        continue # 跳過空行

 

3. 異常

異常會中斷程序的正常控制流。使用raise語句可以引發異常。raise語句的一般格式是raise Exception([value]),其中Exception是異常類型,而value是一個指定異常相關細節的可選值,例如:

raise RuntimeError("unrecoverable Error")

如果raise語句沒有帶任何參數,將會再次引發最近一次生成的異常。使用try和except語句可以捕捉異常,例如:

try:
    f = open('foo')
except IOError as e:
    statements

出現異常時,解釋器將停止執行try代碼塊中的語句,並尋找可匹配該異常的except子句。執行完except子句後,控制權就會傳遞給出現在try-except代碼塊之後的第一條語句。try-except語句可以嵌套使用。如果異常傳遞到程序的最頂級卻仍未被捕獲,解釋器就會終止程序運行。
except語句的可選修飾符as var提供了一個變量名稱,如果出現異常,就會在其中放置一個提供給raise語句的異常類型的實例。異常處理程序可以檢查該值,也可以使用isinstance()函數檢查異常類型。
處理程序可以捕獲多種類型的異常,使用Exception可以捕獲除與程序退出相關之外的所有異常,例如:

try:
    do something
except (IOError, TypeError) as e:
    # 處理I/O、類型異常
except Exception as e:
    # 處理所有異常

使用except語句時如果不帶任何異常類型,也會捕獲所有異常,例如:

try:
    do something
except:
    # 處理所有異常

try語句也支持else子句,它必須跟在最後一個except子句後面。如果try代碼塊中的代碼沒有引發異常,就會執行else子句中的代碼,例如:

try:
    f = open('foo', 'r')
except IOError as e:
    # 處理I/O異常
else:
    data = f.read()
    f.close()

finally語句爲try代碼塊中的代碼定義了結束操作,例如:

f = open('foo', 'r')
try:
    # do something
finally:
    f.close()

finally用於提供一些代碼,無論是否出現錯誤,都必須執行該代碼。如果沒有引發異常,finally子句中的代碼將在try代碼塊中的代碼執行完畢後立即執行。如果引發了異常,控制權首先傳遞給finally子句的第一條語句。這段代碼執行完畢後,將交由另一個異常處理程序進行處理。
如果要創建新異常,就定義父類爲Exception的新類,例如:

class NetworkError(Exception):
    pass

可用如下方式使用這個異常:

raise NetworkError("Cannot find host.")

引發異常時,將提供給raise語句的可選值用作異常的類構造函數的參數。通常它就是一個表示消息的字符串,但用戶自定義的異常可以帶有一個或多個異常值,例如:

class DeviceError(Exception):
    def __init__(self,errno,msg):
        self.args = (errno,msg)
        self.errno = errno
        self.errmsg = msg
raise DeviceError(1, 'Not Responding')

包含__init__()方法參數的元組賦值給屬性self.args。打印異常跟蹤消息時就需要用到這個屬性。如果不定義該屬性,出現錯誤時,用戶就無法看到關於異常的有用信息。
 

4. 上下文管理與with語句

with語句支持在由上下文管理器對象控制的運行時上下文中執行一系列語句,例如:

with open("debuglog", "a") as f:
    f.write("Debugging\n")
    statements
    f.write("Done\n")

import threading
lock = threading.Lock()
with lock:
    statements

在第一小段代碼中,當控制流離開with語句後面的代碼塊時,with語句將自動關閉已打開的文件。在第二小段代碼中,當控制流進入with語句後面的代碼塊時自動請求一個鎖定,而在控制流離開時又自動釋放了這個鎖定。
with obj語句在控制流進入和離開其後的相關代碼塊時,允許對象obj管理所發生的事情。執行with obj語句時,它執行方法obj.__enter__()來指示正在進入一個新的上下文。當控制流離開該上下文時,就會執行方法obj.__exit__(type, value, traceback)。如果沒有引發異常,__exit__()方法的3個參數均被設爲None。否則,它們將包含與導致控制流離開上下文的異常相關的類型、值和跟蹤信息。__exit__()方法返回True或False,分別指示被引發的異常得到了還是沒有得到處理。
with obj語句接受一個可選的as var說明符,如果指定了該說明符,obj.__enter__()方法的返回值將保存在var中。with語句只對支持上下文管理協議(__enter__()和__exit__()方法)的對象有效。用戶定義的類可以實現這些方法,從而定義它們自己的自定義上下文管理。例如:

class ListTransaction(object):
    def __init__(self, thelist):
        self.thelist = thelist
    def __enter__(self):
        self.workingcopy = list(self.thelist)
        return self.workingcopy
    def __exit__(self, type, value, tb):
        if type is None:
            self.thelist[:] = self.workingcopy
        return False

 

5. 斷言與debug

assert語句可以在程序中引入調試代碼。assert的一般格式爲:

    assert test [, msg]

其中test是一個表達式,其值應該爲True或False。如果test求值爲False,assert就會引發AssertionError異常並使用在assert中提供的可選消息msg,例如:

    def write_date(file, data):
        assert file, "write_data: file not defined"

除了assert語句之外,Python還提供內置的只讀變量__debug__,除非解釋器運行在最優模式中,不則它的值爲True。程序可以在需要時檢查這個變量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章