欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python中的with語句與上下文管理器學(xué)習(xí)總結(jié)

 更新時(shí)間:2016年06月28日 16:19:11   作者:指尖跳動(dòng)的精靈  
在Python中作為上下文管理器的對(duì)象可以使用with語句,提供上下文管理器的contextlib模塊的使用則是Python編程中的高級(jí)技巧,下面我們就來詳細(xì)整理一下Python中的with語句與上下文管理器學(xué)習(xí)總結(jié):

0、關(guān)于上下文管理器
上下文管理器是可以在with語句中使用,擁有__enter__和__exit__方法的對(duì)象。

with manager as var:
  do_something(var)

相當(dāng)于以下情況的簡(jiǎn)化:

var = manager.__enter__()
try:
  do_something(var)
finally:
  manager.__exit__()

換言之,PEP 343中定義的上下文管理器協(xié)議允許將無聊的try...except...finally結(jié)構(gòu)抽象到一個(gè)單獨(dú)的類中,僅僅留下關(guān)注的do_something部分。

__enter__方法首先被調(diào)用。它可以返回賦給var的值。as部分是可選的:如果它不出現(xiàn),enter的返回值簡(jiǎn)單地被忽略。
with語句下的代碼被執(zhí)行。就像try子句,它們或者成功執(zhí)行到底,或者break,continue或return,或者可以拋出異常。無論哪種情況,該塊結(jié)束后,__exit__方法被調(diào)用。如果拋出異常,異常信息被傳遞給__exit__,這將在下一章節(jié)討論。通常情況下,異??杀缓雎?,就像在finally子句中一樣,并且將在__exit__結(jié)束后重新拋出。
比如說我們想確認(rèn)一個(gè)文件在完成寫操作之后被立即關(guān)閉:

>>> class closing(object):
...  def __init__(self, obj):
...   self.obj = obj
...  def __enter__(self):
...   return self.obj
...  def __exit__(self, *args):
...   self.obj.close()
>>> with closing(open('/tmp/file', 'w')) as f:
...  f.write('the contents\n')

這里我們確保了當(dāng)with塊退出時(shí)調(diào)用了f.close()。因?yàn)殛P(guān)閉文件是非常常見的操作,該支持已經(jīng)出現(xiàn)在file類之中。它有一個(gè)__exit__方法調(diào)用close,并且本身可作為上下文管理器。

>>> with open('/tmp/file', 'a') as f:
...  f.write('more contents\n')

try...finally常見的用法是釋放資源。各種不同的情況實(shí)現(xiàn)相似:在__enter__階段資源被獲得,在__exit__階段釋放,如果拋出異常也被傳遞。正如文件操作,往往這是對(duì)象使用后的自然操作,內(nèi)置支持使之很方便。每一個(gè)版本,Python都在更多的地方提供支持。

1、如何使用上下文管理器:

如何打開一個(gè)文件,并寫入"hello world"

filename="my.txt"
mode="w"
writer=open(filename,mode)
writer.write("hello world")
writer.close()

當(dāng)發(fā)生異常時(shí)(如磁盤寫滿),就沒有機(jī)會(huì)執(zhí)行第5行。當(dāng)然,我們可以采用try-finally語句塊進(jìn)行包裝:

writer=open(filename,mode)
try:
  writer.write("hello world")
finally:
  writer.close()

當(dāng)我們進(jìn)行復(fù)雜的操作時(shí),try-finally語句就會(huì)變得丑陋,采用with語句重寫:

with open(filename,mode) as writer:
  writer.write("hello world")

as指代了從open()函數(shù)返回的內(nèi)容,并把它賦給了新值。with完成了try-finally的任務(wù)。

2、自定義上下文管理器

with語句的作用類似于try-finally,提供一種上下文機(jī)制。要應(yīng)用with語句的類,其內(nèi)部必須提供兩個(gè)內(nèi)置函數(shù)__enter__和__exit__。前者在主體代碼執(zhí)行前執(zhí)行,后者在主體代碼執(zhí)行后執(zhí)行。as后面的變量,是在__enter__函數(shù)中返回的。

class echo():
  def output(self):
    print "hello world"
  def __enter__(self):
    print "enter"
    return self #可以返回任何希望返回的東西
  def __exit__(self,exception_type,value,trackback):
    print "exit"
    if exception_type==ValueError:
      return True
    else:
      return Flase
 
>>>with echo as e:
  e.output()

輸出:
enter
hello world
exit
完備的__exit__函數(shù)如下:
def __exit__(self,exc_type,exc_value,exc_tb)

其中,exc_type:異常類型;exc_value:異常值;exc_tb:異常追蹤信息

當(dāng)__exit__返回True時(shí),異常不傳播

3、contextlib模塊

contextlib模塊的作用是提供更易用的上下文管理器,它是通過Generator實(shí)現(xiàn)的。contextlib中的contextmanager作為裝飾器來提供一種針對(duì)函數(shù)級(jí)別的上下文管理機(jī)制,常用框架如下:

from contextlib import contextmanager
@contextmanager
def make_context():
  print 'enter'
  try:
    yield "ok"
  except RuntimeError,err:
    print 'error',err
  finally:
    print 'exit'
    
>>>with make_context() as value:
  print value

   
輸出為:

  enter
  ok
  exit

其中,yield寫入try-finally中是為了保證異常安全(能處理異常)as后的變量的值是由yield返回。yield前面的語句可看作代碼塊執(zhí)行前操作,yield之后的操作可以看作在__exit__函數(shù)中的操作。

以線程鎖為例:

@contextlib.contextmanager
def loudLock():
  print 'Locking'
  lock.acquire()
  yield
  print 'Releasing'
  lock.release()
 
with loudLock():
  print 'Lock is locked: %s' % lock.locked()
  print 'Doing something that needs locking'
 
#Output:
#Locking
#Lock is locked: True
#Doing something that needs locking
#Releasing

4、contextlib.nested:減少嵌套

對(duì)于:

with open(filename,mode) as reader:
  with open(filename1,mode1) as writer:
    writer.write(reader.read())

可以通過contextlib.nested進(jìn)行簡(jiǎn)化:

with contextlib.nested(open(filename,mode),open(filename1,mode1)) as (reader,writer):
  writer.write(reader.read())

在python 2.7及以后,被一種新的語法取代:

with open(filename,mode) as reader,open(filename1,mode1) as writer:
  writer.write(reader.read())

5、contextlib.closing()

file類直接支持上下文管理器API,但有些表示打開句柄的對(duì)象并不支持,如urllib.urlopen()返回的對(duì)象。還有些遺留類,使用close()方法而不支持上下文管理器API。為了確保關(guān)閉句柄,需要使用closing()為它創(chuàng)建一個(gè)上下文管理器(調(diào)用類的close方法)。

import contextlib
class myclass():
  def __init__(self):
    print '__init__'
  def close(self):
    print 'close()'
   
with contextlib.closing(myclass()):
  print 'ok'

   
輸出:

__init__
ok
close()

相關(guān)文章

  • Python+SQLAlchemy輕松實(shí)現(xiàn)管理數(shù)據(jù)庫

    Python+SQLAlchemy輕松實(shí)現(xiàn)管理數(shù)據(jù)庫

    QLAlchemy是一個(gè)強(qiáng)大的ORM(對(duì)象關(guān)系映射)庫,它允許您通過Python代碼與關(guān)系型數(shù)據(jù)庫進(jìn)行交互,本文我們將學(xué)習(xí)如何使用Python和SQLAlchemy庫來輕松管理數(shù)據(jù)庫,需要的可以參考下
    2023-05-05
  • pandas之分組groupby()的使用整理與總結(jié)

    pandas之分組groupby()的使用整理與總結(jié)

    這篇文章主要介紹了pandas之分組groupby()的使用整理與總結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Python中turtle作圖示例

    Python中turtle作圖示例

    這篇文章主要介紹了Python中turtle作圖示例,分享了幾則turtle作圖的小實(shí)例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • 一篇文章帶你搞懂Python類的相關(guān)知識(shí)

    一篇文章帶你搞懂Python類的相關(guān)知識(shí)

    今天我們要說的是面向?qū)ο蟮暮诵?----類,類能幫我們把復(fù)雜的事情變得有條理,有順序,希望大家通過學(xué)習(xí)類能改善自己的編碼風(fēng)格,使代碼變得更為好看,更加通俗易懂,需要的朋友可以參考下
    2021-05-05
  • Python安裝模塊的常見問題及解決方法

    Python安裝模塊的常見問題及解決方法

    下面小編就為大家分享一篇Python安裝模塊的常見問題及解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-02-02
  • 利用python實(shí)現(xiàn)3種梯度下降算法

    利用python實(shí)現(xiàn)3種梯度下降算法

    梯度下降法是一種優(yōu)化算法,用于求解函數(shù)的最小值或最大值,它通過迭代的方式,沿著函數(shù)的梯度方向逐步調(diào)整參數(shù),以找到函數(shù)的極值點(diǎn),本文給大家介紹了利用python實(shí)現(xiàn)3種梯度下降算法,需要的朋友可以參考下
    2023-12-12
  • Django框架HttpResponse和HttpRequest對(duì)象學(xué)習(xí)

    Django框架HttpResponse和HttpRequest對(duì)象學(xué)習(xí)

    這篇文章主要介紹了Django框架HttpResponse和HttpRequest對(duì)象學(xué)習(xí),有需要的朋友可以借鑒參考下,希望可以有所幫助,祝大家早日升職加薪
    2021-09-09
  • python刪除過期文件的方法

    python刪除過期文件的方法

    這篇文章主要介紹了python刪除過期文件的方法,涉及Python日期與文件的相關(guān)操作技巧,需要的朋友可以參考下
    2015-05-05
  • pytho多張圖片的無損拼接的實(shí)現(xiàn)示例

    pytho多張圖片的無損拼接的實(shí)現(xiàn)示例

    很多人都會(huì)是用PS進(jìn)行拼接,本文主要介紹了pytho多張圖片的無損拼接的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Python通過PIL獲取圖片主要顏色并和顏色庫進(jìn)行對(duì)比的方法

    Python通過PIL獲取圖片主要顏色并和顏色庫進(jìn)行對(duì)比的方法

    這篇文章主要介紹了Python通過PIL獲取圖片主要顏色并和顏色庫進(jìn)行對(duì)比的方法,實(shí)例分析了Python通過PIL模塊操作圖片的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03

最新評(píng)論