簡體   English   中英

您將如何在 except 子句中捕獲 python 異常

[英]How would you catch python Exception inside an except clause

您將如何在 python 的異常中捕獲異常?

考慮以下情況

bak_filename = filename + ".bak"
#This try is needed because if bak_filename existed, rename will fail
try:
   os.rename(filename, bak_filename)
except WindowsError:
   #However, os.remove may still fail e.g. file in use. How would you handle this exception within except clause ?
   #try and except around this os.remove?  
   os.remove(bak_filename)

   os.rename(filename, bak_filename)

任何想法:

  1. 重寫以避免重復嘗試

  2. 不一定是這個例子,但在某些情況下我們無法重寫,你將如何處理雙重嘗試

避免所有這些異常包裝的解決方案是使用shutil.move

shutil.move(filename, bak_filename)

如果目標已存在但不是目錄,則可能會根據 os.rename() 語義被覆蓋。

如果目標位於當前文件系統上,則使用 os.rename()。 否則,使用 copy_function 將 src 復制到 dst 然后刪除。 在符號鏈接的情況下,將在 dst 中或作為 dst 創建一個指向 src 目標的新符號鏈接,並且將刪除 src。

所以它基本上做了你想做的事情,但是在所有 python 發行版上都可用的庫中。

請注意,如果文件很大並且目標文件存在並且os.rename拒絕覆蓋它(完全取決於操作系統,例如 Windows 將拒絕重命名現有文件),則性能可能會很差,因為回退時os.rename拋出OSError正在復制源然后刪除。 實現不會嘗試刪除文件然后再次重命名,因為如果rename失敗,Python 會假設我們正在嘗試跨文件系統重命名,並且在這種情況下需要復制+刪除(這正是 Unix mv的工作方式)。

try:
    os.rename(src, real_dst)
except OSError:
    if os.path.islink(src):
        ...
    else:
        copy_function(src, real_dst)
        os.unlink(src)

要解決可能存在的文件,可以執行包含在try/except OSError語句中的先前os.remove調用。

try:
   os.remove(bak_filename)
except OSError:
   pass
shutil.move(filename, bak_filename)  # or os.rename(filename, bak_filename)

當然,如果bak_filename被鎖定/不可刪除, shutil.mode仍然可以引發異常。 另請注意,如果我們嘗試刪除目標文件, os.rename將與shutil.move一樣好。 如果無法刪除目標文件,則無論如何操作都不會成功。

您可以閱讀更多關於異常鏈接的信息。 但是,這是針對 Python 3

在 Python 2 中,您可以將異常存儲在變量中,然后像這樣顯式地再次引發它:

try:
    do something
except Exception as e:
    try:
        do something again
    except:
        pass
    raise e

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM