亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Python with用法:自動(dòng)關(guān)閉文件進(jìn)程

系統(tǒng) 1747 0

實(shí)際上,Python 提供了 with 語(yǔ)句來(lái)管理資源關(guān)閉。比如可以把打開(kāi)的文件放在 with 語(yǔ)句中,這樣 with 語(yǔ)句就會(huì)幫我們自動(dòng)關(guān)閉文件。

with 語(yǔ)句的語(yǔ)法格式如下:

            
with context expression [as target(s)]:
  with 代碼塊
          

在上面的語(yǔ)法格式中,context_expression 用于創(chuàng)建可自動(dòng)關(guān)閉的資源。

例如,程序使用 with 語(yǔ)句來(lái)讀取文件:

            
import codecs
# 使用with語(yǔ)句打開(kāi)文件,該語(yǔ)句會(huì)負(fù)責(zé)關(guān)閉文件
with codecs.open("readlines_test.py", 'r', 'utf-8', buffering=True) as f:
  for line in f:
    print(line, end='')
          

程序也可以使用 with 語(yǔ)句來(lái)處理通過(guò) fileinput.input 合并的多個(gè)文件,例如如下程序:

            
import fileinput
# 使用with語(yǔ)句打開(kāi)文件,該語(yǔ)句會(huì)負(fù)責(zé)關(guān)閉文件
with fileinput.input(files=('test.txt', 'info.txt')) as f:
  for line in f:
    print(line, end='')
          

上面兩個(gè)程序都使用了 with 語(yǔ)句來(lái)管理資源,因此它們都不需要顯式關(guān)閉文件。

那么,with 語(yǔ)句的實(shí)現(xiàn)原理是什么?其實(shí)很簡(jiǎn)單,使用 with 語(yǔ)句管理的資源必須是一個(gè)實(shí)現(xiàn)上下文管理協(xié)議(context manage protocol)的類(lèi),這個(gè)類(lèi)的對(duì)象可被稱(chēng)為上下文管理器。要實(shí)現(xiàn)上下文管理協(xié)議,必須實(shí)現(xiàn)如下兩個(gè)方法:

  • context_manager.__enter__():進(jìn)入上下文管理器自動(dòng)調(diào)用的方法。該方法會(huì)在 with 代碼塊執(zhí)行之前執(zhí)行。如果 with 語(yǔ)句有 as子句,那么該方法的返回值會(huì)被賦值給 as 子句后的變量;該方法可以返回多個(gè)值,因此,在 as 子句后面也可以指定多個(gè)變量(多個(gè)變量必須由“()”括起來(lái)組成元組)。
  • context_manager.__exit__(exc_type, exc_value, exc_traceback):退出上下文管理器自動(dòng)調(diào)用的方法。該方法會(huì)在 with 代碼塊執(zhí)行之后執(zhí)行。如果 with 代碼塊成功執(zhí)行結(jié)束,程序自動(dòng)調(diào)用該方法,調(diào)用該方法的三個(gè)參數(shù)都為 None:如果 with 代碼塊因?yàn)楫惓6兄梗绦蛞沧詣?dòng)調(diào)用該方法,使用 sys.exc_info 得到的異常信息將作為調(diào)用該方法的參數(shù)。

通過(guò)上面的介紹不難發(fā)現(xiàn),只要一個(gè)類(lèi)實(shí)現(xiàn)了 __enter__() 和 __exit__(exc_type, exc_value, exc_traceback) 方法,程序就可以使用 with 語(yǔ)句來(lái)管理它;通過(guò) __exit__() 方法的參數(shù),即可判斷出 with 代碼塊執(zhí)行時(shí)是否遇到了異常。

換而言之,上面程序所用的文件對(duì)象、FileInput 對(duì)象,其實(shí)都實(shí)現(xiàn)了這兩個(gè)方法,因此它們都可以接受 with 語(yǔ)句的管理。

下面我們自定義一個(gè)實(shí)現(xiàn)上下文管理協(xié)議的類(lèi),并使用 with 語(yǔ)句來(lái)管理它:

            
class FkResource:
  def __init__(self, tag):
    self.tag = tag
    print('構(gòu)造器,初始化資源: %s' % tag)
  # 定義__enter__方法,with體之前的執(zhí)行的方法
  def __enter__(self):
    print('[__enter__ %s]: ' % self.tag)
    # 該返回值將作為as子句中變量的值
    return 'fkit' # 可以返回任意類(lèi)型的值
  # 定義__exit__方法,with體之后的執(zhí)行的方法
  def __exit__(self, exc_type, exc_value, exc_traceback):
    print('[__exit__ %s]: ' % self.tag)
    # exc_traceback為None,代表沒(méi)有異常
    if exc_traceback is None:
      print('沒(méi)有異常時(shí)關(guān)閉資源')
    else:
      print('遇到異常時(shí)關(guān)閉資源')
      return False  # 可以省略,默認(rèn)返回None也被看做是False
with FkResource('孫悟空') as dr:
  print(dr)
  print('[with代碼塊] 沒(méi)有異常')
print('------------------------------')
with FkResource('白骨精'):
  print('[with代碼塊] 異常之前的代碼')
  raise Exception
  print('[with代碼塊] ~~~~~~~~異常之后的代碼')
          

上面程序定義了一個(gè) FkResource 類(lèi),該類(lèi)定義了 __enter__() 和 __exit__() 兩個(gè)方法,因此該類(lèi)的對(duì)象可以被 with 語(yǔ)句管理:

  • 程序在執(zhí)行 with 代碼塊之前,會(huì)執(zhí)行 __enter__() 方法,并將該方法的返回值賦值給 as 子句后的變量。
  • 程序在執(zhí)行 with 代碼塊之后,會(huì)執(zhí)行 __exit__() 方法,可以根據(jù)該方法的參數(shù)來(lái)判斷 with 代碼塊是否有異常。

程序兩次使用 with 語(yǔ)句管理 FkResource 對(duì)象。第一次,with 代碼塊沒(méi)有出現(xiàn)異常。第二次,with 代碼塊出現(xiàn)了異常。大家可以看到,使用 with 語(yǔ)句兩次對(duì) FkResource 的管理略有差異(主要是在 __exit()__ 方法中略有差異)。

運(yùn)行上面的程序,可以看到如下輸出結(jié)果:

            
構(gòu)造器,初始化資源: 孫悟空
[__enter__ 孫悟空]:
fkit
[with代碼塊] 沒(méi)有異常
[__exit__ 孫悟空]:
沒(méi)有異常時(shí)關(guān)閉資源
------------------------------
構(gòu)造器,初始化資源: 白骨精
[__enter__ 白骨精]:
[with代碼塊] 異常之前的代碼
[__exit__ 白骨精]:
遇到異常時(shí)關(guān)閉資源
Traceback (most recent call last):
 File "C:\Users\mengma\Desktop\1.py", line 26, in 
            
              
  raise Exception
Exception
            
          

從上面的輸出結(jié)果來(lái)看,使用 with 語(yǔ)句管理資源,程序總可以在進(jìn)入 with 代碼塊之前自動(dòng)執(zhí)行 __enter__() 方法,無(wú)論 with 代碼塊是否有異常,這個(gè)部分都是一樣的,而且 __enter__() 方法的返回值被賦值給了 as 子句后的變量,如上面的 ① 號(hào)輸出信息所示。

對(duì)于 with 代碼塊有異常和無(wú)異常這兩種情況,此時(shí)主要通過(guò) exit() 方法的參數(shù)進(jìn)行判斷,程序可針對(duì) with 代碼塊是否有異常分別進(jìn)行處理,如程序中代碼所示。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 尤物久久99热国产综合 | 国产中文欧美 | 久久99久久 | 爱爱永久免费视频网站 | 国产91在线免费观看 | 日本亚洲视频 | 久久免费久久 | 四虎影院精品 | 在线免费福利 | 久久桃花网 | 国产色产综合色产在线观看视频 | 久久久7777888精品 | 国产精品亚洲成在人线 | 日本无翼乌全彩无遮挡动漫 | 欧美国产片 | 精品国产91在线网 | 91尤物国产尤物福利在线 | 亚洲欧美成人综合久久久 | 99热这里只有精品69 | 日韩欧美小视频 | 久久精品免费观看视频 | 人人干人人干 | 久久99深爱久久99精品 | 久久综合久| 亚洲综合一 | 99综合| 免费欧美一级片 | 日韩亚洲一区中文字幕 | 视频一区免费 | 国产二区在线播放 | 久久久青草青青国产亚洲免观 | 久热只有精品 | 久99久精品免费视频热77 | 亚洲一区二区欧美 | 亚洲综合伦理一区 | 免费操片 | 日本一区高清 | 香蕉久久精品 | 国产夜色视频 | 日本免费一区二区三区中文 | 亚欧美|