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

在Python 3中緩存Exception對象會造成什么后果?

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

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

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

舉例:

堆棧信息錯誤很好理解,舉一個意外破壞運行數(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()

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

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

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

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


結(jié)論:

在Python 3中,最佳實踐是:

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

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

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

相關(guān)文章

  • Python中的文件輸入輸出問題

    Python中的文件輸入輸出問題

    這篇文章主要介紹了Python中的文件輸入輸出問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Python爬取股票信息,并可視化數(shù)據(jù)的示例

    Python爬取股票信息,并可視化數(shù)據(jù)的示例

    這篇文章主要介紹了Python爬取股票信息,并可視化數(shù)據(jù)的示例,幫助大家更好的理解和使用python爬蟲,感興趣的朋友可以了解下
    2020-09-09
  • Python六大開源框架對比

    Python六大開源框架對比

    在這篇文章里,我們將為Python Web開發(fā)者回顧基于Python的6大Web應(yīng)用框架。無論你是出于愛好還是需求,這六大框架都可能會成為你工作上不錯的得力助手。
    2015-10-10
  • python通過加號運算符操作列表的方法

    python通過加號運算符操作列表的方法

    這篇文章主要介紹了python通過加號運算符操作列表的方法,實例分析了Python使用加號運算符實現(xiàn)列表追加的方法,需要的朋友可以參考下
    2015-07-07
  • 使用python實現(xiàn)一個簡單的圖片爬蟲

    使用python實現(xiàn)一個簡單的圖片爬蟲

    在本文中,我們將學習如何使用Python創(chuàng)建一個簡單的圖片爬蟲,我們將利用requests庫來發(fā)送HTTP請求,BeautifulSoup庫來解析HTML頁面,以及os和shutil庫來下載和保存圖片,通過這個教程,你將學會如何爬取網(wǎng)頁上的圖片并保存到本地,需要的朋友可以參考下
    2024-02-02
  • keras的get_value運行越來越慢的解決方案

    keras的get_value運行越來越慢的解決方案

    這篇文章主要介紹了keras的get_value運行越來越慢的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • python中的None與NULL用法說明

    python中的None與NULL用法說明

    這篇文章主要介紹了python中的None與NULL用法說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • 一些讓Python代碼簡潔的實用技巧總結(jié)

    一些讓Python代碼簡潔的實用技巧總結(jié)

    隨著項目代碼行數(shù)的增加,不可避免的遇到軟件架構(gòu)腐敗的問題,所以如何寫出簡潔的代碼至關(guān)重要,這篇文章主要給大家介紹了一些讓Python代碼簡潔的實用技巧,需要的朋友可以參考下
    2021-08-08
  • Python通過調(diào)用有道翻譯api實現(xiàn)翻譯功能示例

    Python通過調(diào)用有道翻譯api實現(xiàn)翻譯功能示例

    這篇文章主要介紹了Python通過調(diào)用有道翻譯api實現(xiàn)翻譯功能,結(jié)合實例形式分析了基于Python實現(xiàn)的有道翻譯api調(diào)用相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07
  • Django 導(dǎo)出 Excel 代碼的實例詳解

    Django 導(dǎo)出 Excel 代碼的實例詳解

    本篇文章主要介紹了Django 導(dǎo)出 Excel 代碼的實例詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08

最新評論

阳曲县| 巢湖市| 收藏| 普陀区| 岚皋县| 东兰县| 拜泉县| 渑池县| 秦皇岛市| 阳高县| 巴彦淖尔市| 彭水| 正安县| 达拉特旗| 叶城县| 陵川县| 荣成市| 临潭县| 延吉市| 汕尾市| 高邮市| 云梦县| 锡林浩特市| 广水市| 芮城县| 罗定市| 怀宁县| 栾城县| 如东县| 广德县| 贞丰县| 徐汇区| 库尔勒市| 新晃| 明水县| 广汉市| 舟山市| 隆回县| 四子王旗| 凤凰县| 沂水县|