您如何在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)
有任何想法:
重写以避免两次 try ?
不一定是这个示例,但是在某些情况下我们无法重写,您将如何处理两次 try ?
答案 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.rename
与shutil.move
一样好。如果无法删除目标文件,则该操作将无法成功。
答案 1 :(得分:0)
您可以在Exception Chaining上阅读更多内容。但是,这是针对Python 3
在Python 2中,您可以将异常存储在变量中,然后像这样显式地再次引发它:
try:
do something
except Exception as e:
try:
do something again
except:
pass
raise e