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

python try...finally...的實(shí)現(xiàn)方法

 更新時(shí)間:2020年11月25日 09:18:27   作者:kingron  
這篇文章主要介紹了python try...finally...的實(shí)現(xiàn)方法,幫助大家更好的理解和使用python,感興趣的朋友可以了解下

1. 關(guān)于 try.. finally..

假如上帝用 python 為每一個(gè)來到世界的生物編寫程序,那么除去中間過程的種種復(fù)雜實(shí)現(xiàn),最不可避免的就是要保證每個(gè)實(shí)例最后都要掛掉。代碼可簡(jiǎn)寫如下:

try:
  born() # 出生

  # 正常降臨世界
  # do something..

except ValueError:
  # 安排錯(cuò)誤
  # do something...

except AttributeError:
  # 特征錯(cuò)誤
  # do something...

except TypeError:
  # 種類錯(cuò)誤
  # do something...

... # 等等雜七雜八的錯(cuò)誤

finally:
  go_die() # 掛掉
  come_to_see_me() # 然后來見我
  reincarnate() # 下一輪,安排!

這就是 finally 的作用和實(shí)例。就算捕獲異常后再次出現(xiàn)異常,最終也能保證 go_die 方法會(huì)執(zhí)行,但是,如果 go_die 方法出現(xiàn)錯(cuò)誤,那么就不能正常去見上帝了。為了保證每個(gè)生物(不管有沒有掛掉)都能見到上帝他老人家,并開始下一個(gè)輪回(不管有沒有見到),需要做如下處理:

...

finally:
  try:
    go_die()
  finally:
    try:
      come_to_see_me()
    finally:
      reincarnate()

OK,功能雖然實(shí)現(xiàn)了,但按照 The Zen of Python 所說:Flat is better than nested.(扁平優(yōu)于嵌套),那么這段代碼就略顯丑陋了。為了遵循 python 美學(xué),我們可以對(duì)這段進(jìn)行優(yōu)化,使它看起來更為美觀。

2. 錯(cuò)誤的上下文:__context__

在此之前,需要引入一個(gè)新的概念: __context__,__context__ 的字面意思就是上下文,它屬于錯(cuò)誤的一個(gè)屬性。在錯(cuò)誤捕獲中,它意味著當(dāng)你處理一個(gè)錯(cuò)誤時(shí),另一個(gè)錯(cuò)誤發(fā)生了。也就是說,你所捕獲的錯(cuò)誤雖然被成功捕獲了,但當(dāng)捕獲完成時(shí),你的一些操作導(dǎo)致另一個(gè)錯(cuò)誤發(fā)生,而這個(gè)錯(cuò)誤并沒有被捕獲。通常情況下,如果處理的好,那么當(dāng)前錯(cuò)誤的 __context__ 的值為 None,如果處理不好那就是你所捕獲的錯(cuò)誤。比如下面的代碼:

def type_err():
  raise TypeError('this is a type error.')

def after_type_err():
  raise ValueError('this is a value error.')

try:
  type_err()
except TypeError:
  after_type_err()

執(zhí)行結(jié)果為:

Traceback (most recent call last):
 File "<ipython-input-4-189a22d65266>", line 8, in <module>
  type_err()
 File "<ipython-input-4-189a22d65266>", line 2, in type_err
  raise TypeError('this is a type error.')
TypeError: this is a type error.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
 File "C:\Users\lineu\AppData\Local\Programs\Python\Python37\lib\site-packages\IPython\core\interactiveshell.py", line 3326, in run_code
  exec(code_obj, self.user_global_ns, self.user_ns)
 File "<ipython-input-4-189a22d65266>", line 10, in <module>
  after_type_err()
 File "<ipython-input-4-189a22d65266>", line 5, in after_type_err
  raise ValueError('this is a value error.')
ValueError: this is a value error.

在上面的錯(cuò)誤信息中,當(dāng)前錯(cuò)誤類型為 ValueError,它的 __context__ 屬性值為 TypeError 實(shí)例,而 TypeError 實(shí)例的 __context__None。

3. FinalExecutor:優(yōu)雅的 finally

有了 __context__ 的概念,我們就可以基于此實(shí)現(xiàn)一個(gè)優(yōu)雅的“輪回”了?;舅悸窞椋阂来螆?zhí)行方法,如果方法報(bào)錯(cuò),那么就將該錯(cuò)誤的 __context__ 值設(shè)置為上一個(gè)錯(cuò)誤(如果有)。最后等到所有方法執(zhí)行完畢,再拋出最后一個(gè)錯(cuò)誤,那么此時(shí)的錯(cuò)誤將包含所有可能被引發(fā)的錯(cuò)誤信息。具體代碼如下:

class FinalExecutor(object):
  """終極執(zhí)行器
  用于確保你所有的方法都會(huì)被執(zhí)行(不管中途有沒有方法報(bào)錯(cuò))
  同時(shí)能看到正確的錯(cuò)誤信息
  """

  def __init__(self):
    self.last_err = None # 保存最近發(fā)生的錯(cuò)誤

  def __enter__(self):
    return self

  def __exit__(self, exc_type, exc_val, exc_tb):
    # 如果有發(fā)生錯(cuò)誤,則拋出
    if self.last_err:
      raise self.last_err

  def call(self, func, *args, **kwargs):
    """調(diào)用執(zhí)行方法"""
    try:
      func(*args, **kwargs)
    except Exception as e:
      # Exception 捕獲所有繼承自它或它子類的錯(cuò)誤類型
      # 捕獲它等于捕獲幾乎所有錯(cuò)誤

      if self.last_err:
        # 將本次錯(cuò)誤的上下文定義為上一次錯(cuò)誤
        e.__context__ = self.last_err

      # 更新為當(dāng)前錯(cuò)誤
      self.last_err = e

我們的終極執(zhí)行器使用示例為:

# 定義 3 個(gè)方法用于測(cè)試
def type_err():
  print('type error')
  raise TypeError('x')


def value_err():
  print('value error')
  raise ValueError('x')


def attr_err():
  print('attr error')
  raise AttributeError('x')


# 使用 with 語(yǔ)句來啟動(dòng)終極執(zhí)行器
with FinalExecutor() as e:
  e.call(type_err)
  e.call(value_err)
  e.call(attr_err)

運(yùn)行可以看到方法最終都被執(zhí)行了,且錯(cuò)誤信息一個(gè)不漏:

type error
value error
attr error
Traceback (most recent call last):
 File "<ipython-input-5-1b07c576630b>", line 19, in call
  func(*args, **kwargs)
 File "<ipython-input-6-d602d89ed0e7>", line 3, in type_err
  raise TypeError('x')
TypeError: x

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
 File "<ipython-input-5-1b07c576630b>", line 19, in call
  func(*args, **kwargs)
 File "<ipython-input-6-d602d89ed0e7>", line 8, in value_err
  raise ValueError('x')
ValueError: x

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
 File "C:\Users\lineu\AppData\Local\Programs\Python\Python37\lib\site-packages\IPython\core\interactiveshell.py", line 3326, in run_code
  exec(code_obj, self.user_global_ns, self.user_ns)
 File "<ipython-input-6-d602d89ed0e7>", line 19, in <module>
  e.call(attr_err)
 File "<ipython-input-5-1b07c576630b>", line 15, in __exit__
  raise self.last_err
 File "<ipython-input-5-1b07c576630b>", line 19, in call
  func(*args, **kwargs)
 File "<ipython-input-6-d602d89ed0e7>", line 13, in attr_err
  raise AttributeError('x')
AttributeError: x

4. 使用 ExitStack

有了我們的終極執(zhí)行器,上帝就可以優(yōu)雅的寫代碼了。為了讓每個(gè)人都能這樣優(yōu)雅的寫 python 代碼,python 為我們提供了一個(gè)封裝好的功能,當(dāng)然它的實(shí)現(xiàn)要比我們的終極執(zhí)行器復(fù)雜一些(考慮的也更周到一些~)。我們可以通過 contextlib 模塊導(dǎo)入該方法并使用:

from contextlib import ExitStack


with ExitStack() as stack:
  stack.callback(type_err)
  stack.callback(value_err)
  stack.callback(attr_err)

注意該 ExitStackFinalExecutor 不同的是,它是倒序執(zhí)行的。

以上就是python try...finally...的實(shí)現(xiàn)方法的詳細(xì)內(nèi)容,更多關(guān)于python try...finally的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python使用signal定時(shí)結(jié)束AsyncIOScheduler任務(wù)的問題

    Python使用signal定時(shí)結(jié)束AsyncIOScheduler任務(wù)的問題

    這篇文章主要介紹了Python使用signal定時(shí)結(jié)束AsyncIOScheduler任務(wù),在使用aiohttp結(jié)合apscheduler的AsyncIOScheduler模擬定點(diǎn)并發(fā)的時(shí)候遇到兩個(gè)問題,針對(duì)每個(gè)問題給大家詳細(xì)介紹,需要的朋友可以參考下
    2021-07-07
  • Python實(shí)現(xiàn)隨機(jī)生成算術(shù)題的示例代碼

    Python實(shí)現(xiàn)隨機(jī)生成算術(shù)題的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)隨機(jī)生成算術(shù)題的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-04-04
  • python實(shí)現(xiàn)局部圖像放大

    python實(shí)現(xiàn)局部圖像放大

    這篇文章主要介紹了python實(shí)現(xiàn)局部圖像放大,畫中畫形式展示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • python文件讀取時(shí)順序錯(cuò)誤的問題及解決

    python文件讀取時(shí)順序錯(cuò)誤的問題及解決

    這篇文章主要介紹了python文件讀取時(shí)順序錯(cuò)誤的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Python 求數(shù)組局部最大值的實(shí)例

    Python 求數(shù)組局部最大值的實(shí)例

    今天小編就為大家分享一篇Python 求數(shù)組局部最大值的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • 學(xué)習(xí)Python中一些實(shí)用的庫(kù)

    學(xué)習(xí)Python中一些實(shí)用的庫(kù)

    這篇文章主要介紹了Python學(xué)習(xí)之盤點(diǎn)一些Python中實(shí)用的庫(kù),有需要的同學(xué)可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2021-09-09
  • OpenCV圖像顏色反轉(zhuǎn)算法詳解

    OpenCV圖像顏色反轉(zhuǎn)算法詳解

    這篇文章主要介紹了OpenCV圖像顏色反轉(zhuǎn)算法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • 使用Pandas進(jìn)行時(shí)間序列分析的10個(gè)關(guān)鍵點(diǎn)詳解

    使用Pandas進(jìn)行時(shí)間序列分析的10個(gè)關(guān)鍵點(diǎn)詳解

    這篇文章主要為大家詳細(xì)介紹了使用Pandas進(jìn)行時(shí)間序列分析的10個(gè)關(guān)鍵點(diǎn),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-10-10
  • Python基于gevent實(shí)現(xiàn)文件字符串查找器

    Python基于gevent實(shí)現(xiàn)文件字符串查找器

    這篇文章主要介紹了Python基于gevent實(shí)現(xiàn)文件字符串查找器,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 為2021年的第一場(chǎng)雪錦上添花:用matplotlib繪制雪花和雪景

    為2021年的第一場(chǎng)雪錦上添花:用matplotlib繪制雪花和雪景

    這篇文章主要介紹了為2021年的第一場(chǎng)雪錦上添花:用matplotlib繪制雪花和雪景,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01

最新評(píng)論

藁城市| 辰溪县| 仁布县| 修文县| 山东省| 祁阳县| 宣化县| 屏山县| 武定县| 旌德县| 遵化市| 苗栗市| 大名县| 甘肃省| 易门县| 龙州县| 平阴县| 佛学| 昌平区| 凤翔县| 卢龙县| 龙川县| 南溪县| 石首市| 宁夏| 贵港市| 大冶市| 昌江| 西藏| 长沙市| 依安县| 湟源县| 平乐县| 永善县| 大港区| 岢岚县| 和田县| 阆中市| 天津市| 盖州市| 来安县|