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

在Python 3中緩存Exception對(duì)象會(huì)造成什么后果?

 更新時(shí)間:2021年12月13日 10:18:10   作者:靈劍  
這篇文章主要介紹了在Python 3中緩存Exception對(duì)象到底會(huì)造成什么后果?下面帶著這個(gè)問題一起看看文章的解析,需要的朋友可以參考一下

??Python 3有一個(gè)不太容易被注意到的改進(jìn):異常對(duì)象現(xiàn)在有了一個(gè)新的屬性__traceback__。這個(gè)屬性自動(dòng)保存了traceback列表,當(dāng)每次這個(gè)異常被重新raise出來的時(shí)候,會(huì)自動(dòng)在__traceback__中追加一條記錄。這個(gè)功能對(duì)于異步編程來說非常有幫助:在另一個(gè)線程或者協(xié)程中拋出的異常,被捕獲、傳輸?shù)狡渌胤?,再重新拋出來的時(shí)候,不僅最初的traceback得以保留,每次被重新拋出的記錄也都會(huì)保留下來,這樣異常的traceback就可以提供很細(xì)致的信息。

說完了好處,再來說這個(gè)新功能導(dǎo)致的問題:exception對(duì)象現(xiàn)在是一個(gè)可變的對(duì)象了,每次raise都會(huì)修改這個(gè)對(duì)象。如果將一個(gè)exception對(duì)象拋出多次,就會(huì)保留每次拋出的traceback,可能導(dǎo)致的結(jié)果包括:錯(cuò)誤的堆棧信息;意外地破壞了運(yùn)行數(shù)據(jù);內(nèi)存泄漏等等。

舉例:

堆棧信息錯(cuò)誤很好理解,舉一個(gè)意外破壞運(yùn)行數(shù)據(jù)的例子:

import asyncio
import unittest

async def it(raise_, ignore=True):
    yield 1
    if not ignore:
        await asyncio.sleep(0.01)

    try:
        raise ValueError('test2') from raise_
    except Exception:
        import traceback
        traceback.print_exc()
        if ignore:
            pass
        else:
            raise
    await asyncio.sleep(0.1)
    yield 2


class MyTest(unittest.TestCase):
    def test(self):
        try:
            raise ValueError('testerror')
        except ValueError as e:
            exc = e
        async def task1():
            with self.assertRaises(ValueError):
                async for i in it(exc, False):
                    print("task1: ", i)


        async def task2():
            async for i in it(exc, True):
                print("task2: ", i)


        async def main():
            t1 = asyncio.ensure_future(task1())
            t2 = asyncio.ensure_future(task2())
            await t1
            await t2
        asyncio.get_event_loop().run_until_complete(main())

if __name__ == '__main__':
    unittest.main()

運(yùn)行這段代碼,你會(huì)很驚訝地發(fā)現(xiàn)本來應(yīng)該很快結(jié)束的程序居然卡住了。原因在于assertRaises這個(gè)unittest庫中的函數(shù),為了在保存單元測(cè)試結(jié)果的過程中不要占用太多內(nèi)存,所以在保存異常時(shí)強(qiáng)制清空了異常堆棧中的locals變量。然而因?yàn)檫@個(gè)異常同時(shí)在兩個(gè)Task中被使用,assertRaises捕獲到的異常堆棧中,還有尚未退出的協(xié)程的堆棧,清空了這個(gè)協(xié)程的堆棧會(huì)導(dǎo)致這個(gè)協(xié)程沒有辦法繼續(xù)正常執(zhí)行下去,進(jìn)一步導(dǎo)致相應(yīng)的Future沒有人設(shè)置,等待這個(gè)Future的過程就無法正常結(jié)束了。

再舉一個(gè)內(nèi)存泄漏的例子:這個(gè)例子不在用戶代碼里,而在PyPy3 6.0版本的解釋器里。在PyPy3中,為了提高運(yùn)行速度,關(guān)閉一個(gè)生成器使用的GeneratorExit對(duì)象被解釋器緩存了起來,這導(dǎo)致每次調(diào)用生成器的close方法時(shí),當(dāng)前close的生成器的frame都被保存到了這個(gè)global對(duì)象里,導(dǎo)致了生成器對(duì)象和frame對(duì)象都無法被GC回收,產(chǎn)生了嚴(yán)重的內(nèi)存泄漏。

下面這段代碼在PyPy 3中會(huì)迅速耗盡系統(tǒng)內(nèi)存,而在CPython 3中則沒有問題:

def test():
    yield 1
 
while True:
    t = test()
    t.close()


結(jié)論:

在Python 3中,最佳實(shí)踐是:

  • 永遠(yuǎn)不要持久保存一個(gè)已經(jīng)被拋出過的Exception對(duì)象
  • 每個(gè)被捕獲的Exception對(duì)象,至多被重新raise一次(不管經(jīng)過怎樣的過程)
  • 在需要將同一個(gè)異常廣播到多個(gè)過程時(shí)(例如:多個(gè)過程等待了同一個(gè)異步過程),最好每次都重新復(fù)制整個(gè)Exception對(duì)象,或者為每個(gè)過程創(chuàng)建一個(gè)新的Exception對(duì)象。通過Python 3的新語法raise ... from ...,可以在新的Exception中保留老的traceback。

第三點(diǎn)的一個(gè)特例是asyncio中的Future對(duì)象,如果一個(gè)Future被await了多次,而這個(gè)Future拋出了異常,就會(huì)出現(xiàn)第三種情形,此時(shí)堆棧信息可能會(huì)混亂。

到此這篇關(guān)于在Python 3中緩存Exception對(duì)象會(huì)造成什么后果?的文章就介紹到這了,更多相關(guān)不要在Python 3中緩存Exception對(duì)象內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python爬取氣象臺(tái)每日天氣圖代碼

    python爬取氣象臺(tái)每日天氣圖代碼

    大家好,本篇文章主要講的是python爬取氣象臺(tái)每日天氣圖代碼,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • Python連接Hadoop數(shù)據(jù)中遇到的各種坑(匯總)

    Python連接Hadoop數(shù)據(jù)中遇到的各種坑(匯總)

    這篇文章主要介紹了Python連接Hadoop數(shù)據(jù)中遇到的各種坑,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • PyTorch 編寫代碼遇到的問題及解決方案

    PyTorch 編寫代碼遇到的問題及解決方案

    這篇文章主要介紹了PyTorch 編寫代碼遇到的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。
    2021-06-06
  • python 類的基礎(chǔ)詳解與應(yīng)用

    python 類的基礎(chǔ)詳解與應(yīng)用

    類用于指定對(duì)象的形式,它包含了數(shù)據(jù)表示法和用于處理數(shù)據(jù)的方法。類中的數(shù)據(jù)和方法稱為類的成員。函數(shù)在一個(gè)類中被稱為類的成員
    2021-11-11
  • 基于Python編寫一個(gè)根據(jù)姓名測(cè)性別的小程序

    基于Python編寫一個(gè)根據(jù)姓名測(cè)性別的小程序

    這篇文章主要為大家介紹了如何利用Python編寫一款根據(jù)中文名能猜測(cè)性別的一款界面化的小程序,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-03-03
  • python opencv鼠標(biāo)畫點(diǎn)之cv2.drawMarker()函數(shù)

    python opencv鼠標(biāo)畫點(diǎn)之cv2.drawMarker()函數(shù)

    這篇文章主要給大家介紹了關(guān)于python opencv鼠標(biāo)畫點(diǎn)之cv2.drawMarker()函數(shù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用opencv具有一定的參考下學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2021-10-10
  • Python網(wǎng)絡(luò)編程之ZeroMQ知識(shí)總結(jié)

    Python網(wǎng)絡(luò)編程之ZeroMQ知識(shí)總結(jié)

    這篇文章主要介紹了Python網(wǎng)絡(luò)編程之ZeroMQ知識(shí)總結(jié),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)python的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Python實(shí)現(xiàn)批量繪制遙感影像數(shù)據(jù)的直方圖

    Python實(shí)現(xiàn)批量繪制遙感影像數(shù)據(jù)的直方圖

    這篇文章主要為大家詳細(xì)介紹了如何基于Python中g(shù)dal模塊,實(shí)現(xiàn)對(duì)大量柵格圖像批量繪制直方圖,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-02-02
  • OpenCV灰度化之后圖片為綠色的解決

    OpenCV灰度化之后圖片為綠色的解決

    這篇文章主要介紹了OpenCV灰度化之后圖片為綠色的解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 使用Python將xmind腦圖轉(zhuǎn)成excel用例的實(shí)現(xiàn)代碼(一)

    使用Python將xmind腦圖轉(zhuǎn)成excel用例的實(shí)現(xiàn)代碼(一)

    這篇文章主要介紹了使用Python將xmind腦圖轉(zhuǎn)成excel用例的實(shí)現(xiàn)代碼(一),本文給大家介紹的非常詳細(xì)對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10

最新評(píng)論