麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 操作系統 > 正文

理解Python中的with…as…語法

2024-06-28 16:01:49
字體:
來源:轉載
供稿:網友

先說明一個常見問題,文件打開:

try:    f= open('xxx')    do somethingexcept:    do somethingfinally:    f.close()

其實我個人不止一次在網上看到有這么寫的了,這個是錯的。首先正確的如下:

try:    f= open('xxx')except:    PRint'fail to open'    exit(-1)try:    do somethingexcept:    do somethingfinally:    f.close()

很麻煩不是么,但正確的方法就是這么寫。我們為什么要寫finally,是因為防止程序拋出異常最后不能關閉文件,但是需要關閉文件有一個前提就是文件已經打開了。在第一段錯誤代碼中,如果異常發生在f=open(‘xxx’)的時候,比如文件不存在,立馬就可以知道執行f.close()是沒有意義的。改正后的解決方案就是第二段代碼。

好了言歸正轉,開始討論with語法。

首先我們從下面這個問題談起,try-finally的語法結構:

setthings uptry:    do somethingfinally:    tear things down

這東西是個常見結構,比如文件打開,set things up就表示f=open('xxx')tear things down就表示f.close()。在比如像多線程鎖,資源請求,最終都有一個釋放的需求。Try…finally結構保證了tear things down這一段永遠都會執行,即使上面do something得工作沒有完全執行。

如果經常用這種結構,我們首先可以采取一個較為優雅的辦法,封裝!

defcontrolled_execution(callback):    setthings up    try:        callback(thing)    finally:        tear things down defmy_function(thing):    do something controlled_execution(my_function)

封裝是一個支持代碼重用的好辦法,但是這個辦法很dirty,特別是當do something中有修改一些local variables的時候(變成函數調用,少不了帶來變量作用域上的麻煩)。

另一個辦法是使用生成器,但是只需要生成一次數據,我們用for-in結構去調用他:

defcontrolled_execution():    setthings up    try:        yieldthing    finally:        tear things down         forthing incontrolled_execution():    do something with thing

因為thing只有一個,所以yield語句只需要執行一次。當然,從代碼可讀性也就是優雅的角度來說這簡直是糟糕透了。我們在確定for循環只執行一次的情況下依然使用了for循環,這代碼給不知道的人看一定很難理解這里的循環是什么個道理。

最終的python-dev團隊的解決方案。(python 2.5以后增加了with表達式的語法)

classcontrolled_execution:    def__enter__(self):        setthings up        returnthing    def__exit__(self,type, value, traceback):        tear things down         with controlled_execution() as thing:        do something

在這里,python使用了with-as的語法。當python執行這一句時,會調用__enter__函數,然后把該函數return的值傳給as后指定的變量。之后,python會執行下面do something的語句塊。最后不論在該語句塊出現了什么異常,都會在離開時執行__exit__。另外,__exit__除了用于tear things down,還可以進行異常的監控和處理,注意后幾個參數。要跳過一個異常,只需要返回該函數True即可。下面的樣例代碼跳過了所有的TypeError,而讓其他異常正常拋出。

def__exit__(self,type, value, traceback):    returnisinstance(value, TypeError)

在python2.5及以后,file對象已經寫好了__enter__和__exit__函數,我們可以這樣測試:

>>> f= open("x.txt")>>> f<openfile 'x.txt', mode 'r'at 0x00AE82F0>>>> f.__enter__()<openfile 'x.txt', mode 'r'at 0x00AE82F0>>>> f.read(1)'X'>>> f.__exit__(None,None,None)>>> f.read(1)Traceback (most recent call last):    File"<stdin>", line1,in <module>ValueError: I/O Operation on closedfile

之后,我們如果要打開文件并保證最后關閉他,只需要這么做:

withopen("x.txt") as f:    data= f.read()    do something with data

如果有多個項,我們可以這么寫:

withopen("x.txt") as f1,open('xxx.txt') as f2:    do something with f1,f2

上文說了__exit__函數可以進行部分異常的處理,如果我們不在這個函數中處理異常,他會正常拋出,這時候我們可以這樣寫(python 2.7及以上版本,之前的版本參考使用contextlib.nested這個庫函數):

try:    withopen("a.txt" ) as f :        do somethingexceptxxxError:    do something about exception

總之,with-as表達式極大的簡化了每次寫finally的工作,這對保持代碼的優雅性是有極大幫助的。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 成人av一区二区免费播放 | 亚洲精品欧美在线 | 色毛片 | 日韩电影一区二区三区 | 欧美一级特级 | 成人午夜视频在线观看免费 | 国产黄色录像片 | 国产精品一区99 | 久久毛片免费观看 | 黄色av电影在线播放 | 二区三区四区 | 免费试看av | 国产91久久精品 | 一级黄色国产视频 | 免费国产自久久久久三四区久久 | 免费a级黄色片 | 超级av在线| 国产99久久精品一区二区300 | 国产男人的天堂 | 亚洲va久久久噜噜噜久牛牛影视 | 亚洲性生活视频 | 少妇的肉体的满足毛片 | 成人三级电影网站 | 久久人| av在线免费观看中文字幕 | 成年人福利视频 | 在线看日本 | 草久在线观看视频 | 亚洲国产精品99 | 国产成人在线观看网站 | 久久老司机精品视频 | 国产乱一区二区三区视频 | av免费在线观看国产 | 亚洲一区二区不卡视频 | 91麻豆精品国产91久久久更新资源速度超快 | 精品91av| 欧美成人一区免费视频 | 久久精品视频亚洲 | 精品在线一区二区三区 | 欧美日韩爱爱视频 | 成人黄色小视频网站 |