最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

簡單介紹Python中的try和finally和with方法

 更新時間:2015年05月05日 11:41:04   作者:xrzs  
這篇文章主要介紹了Python中的try和finally和with方法,是Python學(xué)習(xí)當(dāng)中的基礎(chǔ)知識,需要的朋友可以參考下

用 Python 做一件很平常的事情: 打開文件, 逐行讀入, 最后關(guān)掉文件; 進(jìn)一步的需求是, 這也許是程序中一個可選的功能, 如果有任何問題, 比如文件無法打開, 或是讀取出錯, 那么在函數(shù)內(nèi)需要捕獲所有異常, 輸出一行警告并退出. 代碼可能一開始看起來是這樣的
 

def read_file(): 
  try: 
    f = open('yui', 'r') 
    print ''.join(f.readlines()) 
  except: 
    print 'error occurs while reading file'
  finally: 
    f.close()

    不過這顯然無法運作, 因為  f  是在  try  塊中定義的, 而在  finally  中無法引用.

    如果將  f  提取到  try  塊外部, 如
 

def read_file(): 
   f = open('azusa', 'r') 
  try: 
    print ''.join(f.readlines()) 
  except: 
    print 'error occurs while reading file'
  finally: 
    f.close()

那么, 問題在于當(dāng)打開文件失敗, 拋出異常將不會被捕獲.

    挫一點的方法自然是, 再套一層  try  吧
 

def read_file(): 
   try: 
    f = open('sawako', 'r') 
    try: 
      print ''.join(f.readlines()) 
    except: 
      print 'error occurs while reading file'
    finally: 
      f.close() 
   except: 
     print 'error occurs while reading file'

    當(dāng)然這不僅僅是多一層縮進(jìn)挫了, 連警告輸出都白白多一次呢.

    正規(guī)一點的方式是, 使用 Python 引入的  with  結(jié)構(gòu)來解決, 如
 

def readFile(): 
  try: 
     with open('mio', 'r') as f: 
      print ''.join(f.readlines()) 
  except: 
    print 'error occurs while reading file'

    當(dāng)文件打開失敗時, 異常自然會被  except  到; 否則, 在  with  塊結(jié)束之后, 打開的文件將自動關(guān)閉.

    除了打開文件, 還有其它這樣可以用于  with  的東西么? 或者說, 怎么自定義一個什么東西, 讓它能用于  with 呢?
    直接回答后一個問題吧, 秘密在于 Python 虛擬機在  with  塊退出時會去尋找對象的  __exit__  方法并調(diào)用它, 把釋放資源的動作放在這個  __exit__  函數(shù)中就可以了; 另外, 對象還需要一個  __enter__  函數(shù), 當(dāng)進(jìn)入  with 塊時, 這個函數(shù)被調(diào)用, 而它的返回值將作為  as  后引用的值. 一個簡單的例子是
 

class Test: 
  def __init__(self): 
    print 'init'
 
  def __enter__(self): 
    print 'enter'
    return self
 
  def __exit__(self, except_type, except_obj, tb): 
    print except_type 
    print except_obj 
    import traceback 
    print ''.join(traceback.format_tb(tb)) 
    print 'exit'
    return True
 
with Test() as t: 
  raise ValueError('kon!')

    執(zhí)行這一段代碼, 輸出將會是
 

init 
enter 
<type 'exceptions.ValueError'> 
kon! 
 File "test.py", line 17, in <module> 
  raise ValueError('kon!') 
 
exit

     __exit__  函數(shù)接受三個參數(shù), 分別是異常對象類型, 異常對象和調(diào)用棧. 如果  with  塊正常退出, 那么這些參數(shù)將都是  None . 返回  True  表示發(fā)生的異常已被處理, 不再繼續(xù)向外拋出.

    簡單的介紹到此為止, 詳細(xì)的情況可以參考  PEP 343  (這數(shù)字真不錯, 7 3 ).

下面介紹下 with 語句的實例用法 & 高級用法:

Python高端、大氣、上檔次的with語句

在說with語句之前,先看看一段簡單的代碼吧
 

lock = threading.Lock()
...
lock.acquire()
elem = heapq.heappop(heap)
lock.release()

很簡單直觀,多個線程共用一個優(yōu)先級隊列的時候,首先先用互斥鎖lock.acquire()把優(yōu)先級隊列鎖上,然后取元素,再然后lock.release()釋放這個鎖。

雖然看似非常符合邏輯的一個過程,但是里面隱藏著一個巨大的bug:當(dāng)heap里面沒有元素的時候,會拋出一個IndexError異常,再然后堆?;貪L,再然后lock.release()根本不會執(zhí)行,這個鎖就永遠(yuǎn)得不到釋放,因此就發(fā)生了喜聞樂見的死鎖問題。這個也是很多大神們討厭異常的原因。經(jīng)典Java風(fēng)格的解決方案就是
 

lock = threading.Lock()
...
lock.acquire()
try:
  elem = heapq.heappop(heap)
finally:
  lock.release()

這個雖然可以,但是怎么看怎么dirty,和Python優(yōu)雅、簡單的風(fēng)格出入很大。其實,自從Python2.5開始引入了with語句,一切就變得非常簡單:
 

lock = threading.Lock()
...
with lock:
  elem = heapq.heappop(heap)

在此無論以何種方式離開with語句的代碼塊,鎖都會被釋放。
with語句的設(shè)計目的就是為了使得之前需要通過try...finally解決的清理資源問題變得簡單、清晰,它的的用法是
 

with expression [as variable]:
  with-block

其中expression返回一個叫做「context manager」的對象,然后這個對象被賦給variable(如果有的話)?!竎ontext manager」對象有兩個方法,分別是__enter__()和__exit__(),很明顯一個在進(jìn)入with-block時調(diào)用,一個離開with-block的時候調(diào)用。

這樣的對象不需要自己去實現(xiàn),在Python標(biāo)準(zhǔn)庫里面很多API都是已經(jīng)實現(xiàn)了這兩個方法,最常見的一個例子就是讀寫文件的open語句。
 

with open('1.txt', encoding = 'utf-8') as fp:
  lines = fp.readlines()

無論是正常離開還是因為異常原因離開with語句塊,打開的文件資源總是會釋放。
接下去討論一下with語句配合contextlib庫的一些比較實用的方法,比如需要同時打開兩個文件,一個讀一個寫,這個時候就可以這樣寫:
 

from contextlib import nested
...
with nested(open('in.txt'), open('out.txt', 'w')) as (fp_in, fp_out):
  ...

這樣就可以省掉兩個with的語句的嵌套了,另外如果遇到一些還沒有支持「context manager」的API呢?比如urllib.request.urlopen(),這個返回的對象因為不是「context manager」,結(jié)束的時候還需要自己去調(diào)用close方法。
類似這種API,contextlib提供了一個叫做closing方法,它會在離開with語句的時候,自動調(diào)用對象的close方法,因此urlopen也可以這樣寫:
 

from contextlib import closing
...
with closing(urllib.request.urlopen('http://www.yahoo.com')) as f:
  for line in f:
    sys.stdout.write(line)

 用 Python 做一件很平常的事情: 打開文件, 逐行讀入, 最后關(guān)掉文件; 進(jìn)一步的需求是, 這也許是程序中一個可選的功能, 如果有任何問題, 比如文件無法打開, 或是讀取出錯, 那么在函數(shù)內(nèi)需要捕獲所有異常, 輸出一行警告并退出. 代碼可能一開始看起來是這樣的
 

def read_file(): 
  try: 
    f = open('yui', 'r') 
    print ''.join(f.readlines()) 
  except: 
    print 'error occurs while reading file'
  finally: 
    f.close()

    不過這顯然無法運作, 因為  f  是在  try  塊中定義的, 而在  finally  中無法引用.

    如果將  f  提取到  try  塊外部, 如
 

def read_file(): 
   f = open('azusa', 'r') 
  try: 
    print ''.join(f.readlines()) 
  except: 
    print 'error occurs while reading file'
  finally: 
    f.close()

那么, 問題在于當(dāng)打開文件失敗, 拋出異常將不會被捕獲.

    挫一點的方法自然是, 再套一層  try  吧
 

def read_file(): 
   try: 
    f = open('sawako', 'r') 
    try: 
      print ''.join(f.readlines()) 
    except: 
      print 'error occurs while reading file'
    finally: 
      f.close() 
   except: 
     print 'error occurs while reading file'

    當(dāng)然這不僅僅是多一層縮進(jìn)挫了, 連警告輸出都白白多一次呢.

    正規(guī)一點的方式是, 使用 Python 引入的  with  結(jié)構(gòu)來解決, 如
 

def readFile(): 
  try: 
     with open('mio', 'r') as f: 
      print ''.join(f.readlines()) 
  except: 
    print 'error occurs while reading file'

    當(dāng)文件打開失敗時, 異常自然會被  except  到; 否則, 在  with  塊結(jié)束之后, 打開的文件將自動關(guān)閉.

    除了打開文件, 還有其它這樣可以用于  with  的東西么? 或者說, 怎么自定義一個什么東西, 讓它能用于  with 呢?
    直接回答后一個問題吧, 秘密在于 Python 虛擬機在  with  塊退出時會去尋找對象的  __exit__  方法并調(diào)用它, 把釋放資源的動作放在這個  __exit__  函數(shù)中就可以了; 另外, 對象還需要一個  __enter__  函數(shù), 當(dāng)進(jìn)入  with 塊時, 這個函數(shù)被調(diào)用, 而它的返回值將作為  as  后引用的值. 一個簡單的例子是
 

class Test: 
  def __init__(self): 
    print 'init'
 
  def __enter__(self): 
    print 'enter'
    return self
 
  def __exit__(self, except_type, except_obj, tb): 
    print except_type 
    print except_obj 
    import traceback 
    print ''.join(traceback.format_tb(tb)) 
    print 'exit'
    return True
 
with Test() as t: 
  raise ValueError('kon!')

    執(zhí)行這一段代碼, 輸出將會是
 

init 
enter 
<type 'exceptions.ValueError'> 
kon! 
 File "test.py", line 17, in <module> 
  raise ValueError('kon!') 
 
exit

     __exit__  函數(shù)接受三個參數(shù), 分別是異常對象類型, 異常對象和調(diào)用棧. 如果  with  塊正常退出, 那么這些參數(shù)將都是  None . 返回  True  表示發(fā)生的異常已被處理, 不再繼續(xù)向外拋出.

    簡單的介紹到此為止, 詳細(xì)的情況可以參考  PEP 343  (這數(shù)字真不錯, 7 3 ).

下面介紹下 with 語句的實例用法 & 高級用法:

Python高端、大氣、上檔次的with語句

在說with語句之前,先看看一段簡單的代碼吧
 

lock = threading.Lock()
...
lock.acquire()
elem = heapq.heappop(heap)
lock.release()

很簡單直觀,多個線程共用一個優(yōu)先級隊列的時候,首先先用互斥鎖lock.acquire()把優(yōu)先級隊列鎖上,然后取元素,再然后lock.release()釋放這個鎖。

雖然看似非常符合邏輯的一個過程,但是里面隱藏著一個巨大的bug:當(dāng)heap里面沒有元素的時候,會拋出一個IndexError異常,再然后堆?;貪L,再然后lock.release()根本不會執(zhí)行,這個鎖就永遠(yuǎn)得不到釋放,因此就發(fā)生了喜聞樂見的死鎖問題。這個也是很多大神們討厭異常的原因。經(jīng)典Java風(fēng)格的解決方案就是
 

lock = threading.Lock()
...
lock.acquire()
try:
  elem = heapq.heappop(heap)
finally:
  lock.release()

這個雖然可以,但是怎么看怎么dirty,和Python優(yōu)雅、簡單的風(fēng)格出入很大。其實,自從Python2.5開始引入了with語句,一切就變得非常簡單:
 

lock = threading.Lock()
...
with lock:
  elem = heapq.heappop(heap)

在此無論以何種方式離開with語句的代碼塊,鎖都會被釋放。
with語句的設(shè)計目的就是為了使得之前需要通過try...finally解決的清理資源問題變得簡單、清晰,它的的用法是
 

with expression [as variable]:
  with-block

其中expression返回一個叫做「context manager」的對象,然后這個對象被賦給variable(如果有的話)?!竎ontext manager」對象有兩個方法,分別是__enter__()和__exit__(),很明顯一個在進(jìn)入with-block時調(diào)用,一個離開with-block的時候調(diào)用。

這樣的對象不需要自己去實現(xiàn),在Python標(biāo)準(zhǔn)庫里面很多API都是已經(jīng)實現(xiàn)了這兩個方法,最常見的一個例子就是讀寫文件的open語句。
 

with open('1.txt', encoding = 'utf-8') as fp:
  lines = fp.readlines()

無論是正常離開還是因為異常原因離開with語句塊,打開的文件資源總是會釋放。
接下去討論一下with語句配合contextlib庫的一些比較實用的方法,比如需要同時打開兩個文件,一個讀一個寫,這個時候就可以這樣寫:
 

from contextlib import nested
...
with nested(open('in.txt'), open('out.txt', 'w')) as (fp_in, fp_out):
  ...

這樣就可以省掉兩個with的語句的嵌套了,另外如果遇到一些還沒有支持「context manager」的API呢?比如urllib.request.urlopen(),這個返回的對象因為不是「context manager」,結(jié)束的時候還需要自己去調(diào)用close方法。
類似這種API,contextlib提供了一個叫做closing方法,它會在離開with語句的時候,自動調(diào)用對象的close方法,因此urlopen也可以這樣寫:
 

from contextlib import closing
...
with closing(urllib.request.urlopen('http://www.yahoo.com')) as f:
  for line in f:
    sys.stdout.write(line)


相關(guān)文章

  • 解讀torch.nn.GRU的輸入及輸出示例

    解讀torch.nn.GRU的輸入及輸出示例

    這篇文章主要介紹了解讀torch.nn.GRU的輸入及輸出示例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • Python函數(shù)的參數(shù)類型和使用技巧詳解

    Python函數(shù)的參數(shù)類型和使用技巧詳解

    這篇文章主要介紹了Python函數(shù)的參數(shù)類型和使用技巧詳解,函數(shù)指通過專門的代碼組織,用來實現(xiàn)特定功能的代碼段,具有相對的獨立性,可以被其他代碼重復(fù)調(diào)用,需要的朋友可以參考下
    2023-08-08
  • Python實現(xiàn)的json文件讀取及中文亂碼顯示問題解決方法

    Python實現(xiàn)的json文件讀取及中文亂碼顯示問題解決方法

    這篇文章主要介紹了Python實現(xiàn)的json文件讀取及中文亂碼顯示問題解決方法,涉及Python針對json文件的讀取載入、編碼轉(zhuǎn)換等相關(guān)操作技巧,需要的朋友可以參考下
    2018-08-08
  • python write無法寫入文件的解決方法

    python write無法寫入文件的解決方法

    今天小編就為大家分享一篇python write無法寫入文件的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • Python守護(hù)線程用法實例

    Python守護(hù)線程用法實例

    這篇文章主要介紹了Python守護(hù)線程用法,結(jié)合具體實例形式分析了Python守護(hù)線程的功能、使用方法與相關(guān)操作技巧,需要的朋友可以參考下
    2017-06-06
  • python定位xpath 節(jié)點位置的方法

    python定位xpath 節(jié)點位置的方法

    今天小編就為大家分享一篇python定位xpath 節(jié)點位置的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • Python名稱空間與作用域

    Python名稱空間與作用域

    這篇文章主要介紹了Python名稱空間與作用域,名稱空間即存放名字與對象映射?綁定關(guān)系的地方,下文更多相關(guān)介紹需要的小伙伴可以參考一下
    2022-04-04
  • 微信跳一跳小游戲python腳本

    微信跳一跳小游戲python腳本

    這篇文章主要為大家詳細(xì)介紹了微信跳一跳小程序Python腳本,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • pandas merge報錯的解決方案

    pandas merge報錯的解決方案

    這篇文章主要介紹了pandas merge報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • 用Python的Django框架來制作一個RSS閱讀器

    用Python的Django框架來制作一個RSS閱讀器

    這篇文章主要介紹了用Python的Django框架來制作一個RSS閱讀器,通過url feeds來制作訂閱類應(yīng)用同樣是Django之所長,需要的朋友可以參考下
    2015-07-07

最新評論

威远县| 景泰县| 长兴县| 腾冲县| 神池县| 定州市| 桃源县| 敦煌市| 绥德县| 长武县| 焦作市| 多伦县| 皮山县| 平舆县| 盘锦市| 澄江县| 沭阳县| 正宁县| 乐陵市| 股票| 琼海市| 全椒县| 麟游县| 胶南市| 元氏县| 资溪县| 大石桥市| 沙湾县| 上栗县| 弥渡县| 邹平县| 达孜县| 金湖县| 紫金县| 广灵县| 龙海市| 上思县| 林西县| 罗山县| 兰坪| 渑池县|