您如何在except子句中捕获python异常

时间:2019-10-21 19:15:19

标签: python file exception try-catch

您如何在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. 重写以避免两次 try

  2. 不一定是这个示例,但是在某些情况下我们无法重写,您将如何处理两次 try

2 个答案:

答案 0 :(得分:1)

避免所有此类异常包装的解决方案是使用shutil.move

shutil.move(filename, bak_filename)
  

如果目标已经存在但不是目录,则可能会由于os.rename()语义而被覆盖。

     

如果目标位于当前文件系统上,则使用os.rename()。否则,使用copy_function将src复制到dst,然后将其删除。如果是符号链接,则将在dst中或以dst创建指向src目标的新符号链接。

因此,它基本上可以完成您想要做的事情,但是在所有python发行版中都可用的库中。

请注意,如果文件很大且目标文件存在 os.rename会覆盖该文件(完全取决于操作系统,但例如Windows会拒绝),则性能可能会很差。以重命名现有文件),因为os.rename抛出OSError时的后备操作是复制源 then 删除项。该实现不会尝试再次删除文件 then 重命名,因为如果rename失败,Python会假定我们正在尝试在整个文件系统中重命名,并且执行了copy + delete操作在这种情况下(这正是Unix mv的工作方式)。

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

要解决可能存在的文件问题,可以执行os.remove语句中包裹的先前try/except OSError调用。

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

当然,如果bak_filename被锁定/不可删除,shutil.mode仍然可以引发异常。另请注意,如果我们尝试删除目标文件,则os.renameshutil.move一样好。如果无法删除目标文件,则该操作将无法成功。

答案 1 :(得分:0)

您可以在Exception Chaining上阅读更多内容。但是,这是针对Python 3

在Python 2中,您可以将异常存储在变量中,然后像这样显式地再次引发它:

try:
    do something
except Exception as e:
    try:
        do something again
    except:
        pass
    raise e
相关问题