如何安全地确定被捕获的异常的原因?

时间:2017-04-18 15:05:38

标签: python python-3.x exception-handling

在Python中,有许多built-in exceptions可以被各种标准库函数抛出(当然还有其他代码)。由于许多原因,可能会抛出某个异常,您可能想知道它是否因特定原因而被抛出。

例如,在Windows中,如果您尝试在另一个进程锁定文件时移动该文件,则可能会获得PermissionError

PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Path\\to\\the\\file'

在我的情况下,我想确定抛出PermissionError异常的原因是因为我尝试移动的文件被锁定了,我目前通过查看异常中的错误消息来做到这一点我抓住了:

try:
    # Move file
    os.rename(source_path, dest_path)

except PermissionError as e:
    if str(e).find('The process cannot access the file because it is being used by another process') != -1:
        # File not unlocked yet; do something, e.g. wait a moment and try again
    else:
        # Exception thrown for some other reason; do something else

但是,要检查str(e)是否包含特定错误消息作为子字符串并不感到完全安全,因为我还没有看到任何specification消息将被分配当源文件被锁定时由os.rename引发的异常,或者应该抛出什么类型的异常,或者甚至应该抛出异常。因此,这种行为可能会在未来的Python版本中发生变化,或者在不同的Python实现之间发生变化。

那么,如果我们假设会抛出PermissionError异常,我怎么能安全地确定是否因为我试图访问锁定文件而抛出PermissionError异常?或者,如果我们不能假设,我怎样才能安全地实现我的应用程序目前实现的目标?

3 个答案:

答案 0 :(得分:5)

标准python异常使用C errno代码,您可以使用e.errno进行访问。

在mac / linux上,您可以看到posix errno values的列表。

在Windows上,您可以使用e.winerror访问窗口操作系统提供的其他错误代码。然后,您可以使用documentation from microsoft查找正确的代码。

答案 1 :(得分:1)

在Windows上,使用异常字符串是安全的 它始终是'进程无法访问该文件,因为它正由另一个进程使用'

你可以随时

if "The process cannot access the file because it is being used by another process" in str(e):
    #file is locked
    pass

答案 2 :(得分:1)

Lærne是正确的,所有你需要做的就是正确地确定错误的原因是检查它的errno属性。

可用错误符号列表位于errno模块中,您可以通过检查其中定义的符号来导入和使用该模块。一个简单的例子:

import os, errno

try:
    os.remove(filename)
except OSError as e:
    if e.errno != errno.ENOENT:
        raise

重新引发异常if no such file/directory exists