<!-- TOC -->python
<!-- /TOC -->code
看一個例子:對象
def get_result(): a = 3 b = 0 try: b = 3 / 0 except Exception as e: print("ERROR=", e) finally: print("a=", a) if __name__ == "__main__": get_result()
返回結果是:字符串
ERROR= division by zero a= 3
總結:get
try..except..else沒有捕獲到異常,執行else語句
try..except..finally無論是否捕獲到異常,都執行finally語句
python文本文件讀寫的3種方法it
# 第一種方法: file1 = open("test.txt") file2 = open("output.txt", "w") while True: line = file1.readline() # 這裏能夠進行邏輯處理 file2.write(line) if not line: break # 記住文件處理完,關閉是個好習慣 file1.close() file2.close() # 讀文件有3種方法: # - read()將文本文件全部行讀到一個字符串中。 # - readline()是一行一行的讀 # - readlines()是將文本文件中全部行讀到一個list中,文本文件每一行是list的一個元素。 # 優勢:readline()能夠在讀行過程當中跳過特定行。 # 第二種方法:文件迭代器,用for循環的方法 file2 = open("output.txt", "w") for line in open("test.txt"): # 這裏能夠進行邏輯處理 file2.write(line) # 第三種方法: 推薦使用這個方法文件上下文管理器 with open('somefile.txt', 'r') as f: data = f.read() with open('somefile.txt', 'r') as f: for line in f: print(line) with open('somefile.txt', 'w') as f: f.write("hello")
這裏重點說說第三種方法io
打開文件在進行讀寫的時候可能會出現一些異常情況,若是按照常規的f.open
寫法,咱們須要try,except,finally,作異常判斷,而且文件最終無論遇到什麼狀況,都要執行finally f.close()關閉文件,with方法幫咱們實現了finally中f.closefor循環
上下文管理器協議包含__enter__ 和 __exit__
兩個方法。class
with 語句開始運行時,會在上下文管理器對象上調用 __enter__
方法。
with 語句運行結束後,會在上下文管理器對象上調用 __exit__
方法,以此扮演 finally 子句的角色。
最多見的例子是確保關閉文件對象
class T(object): def __enter__(self): print('T.__enter__') return '我是__enter__的返回值' def __exit__(self, exc_type, exc_val, exc_tb): print('T.__exit__') with T() as t: print(t)
返回結果:
T.__enter__ 我是__enter__的返回值 T.__exit__
with之於上下文管理器,就像for之於迭代器同樣。with就是爲了方便上下文管理器的使用。
下文管理器就不得不提一下@contextmanager 裝飾器,它能減小建立上下文管理器的樣板代碼量,
由於不用編寫一個完整的類,定義 __enter__和 __exit__
方法,而只需實現有一個 yield 語句的生成器,生成想讓 __enter__
方法返回的值。
@contextmanager 裝飾器優雅且實用,把三個不一樣的 Python 特性結合到了一塊兒:函數裝飾器、生成器和 with 語句。
在使用 @contextmanager 裝飾的生成器中,yield 語句的做用是把函數的定義體分紅兩部分:
1. yield 語句前面的全部代碼在 with 塊開始時(即解釋器調用` __enter__` 方法時)執行 2. yield 語句後面的代碼在with 塊結束時(即調用 `__exit__` 方法時)執行。
例子:
import sys import contextlib @contextlib.contextmanager def WoHa(n): original_write = sys.stdout.write def reverse_write(text): original_write(text[::-1]) sys.stdout.write = reverse_write yield n sys.stdout.write = original_write return True obj1 = WoHa('你手機拿反了') with obj1 as content: print('哈哈鏡花緣') print(content) print('#### with 執行完畢後,在輸出content: ####') print(content)
返回結果:
緣花鏡哈哈 了反拿機手你 #### with 執行完畢後,在輸出content: #### 你手機拿反了
這裏咱們須要注意的是:
代碼執行到yield時,會產出一個值,這個值會綁定到 with 語句中 as 子句的變量上。執行 with 塊中的代碼時,這個函數會在yield這裏暫停。