首页 文章

如何正确忽略异常

提问于
浏览
634

如果你只是想尝试 - 除了不处理异常,你如何在Python中做到这一点?

以下是正确的方法吗?

try:
    shutil.rmtree(path)
except:
    pass

12 回答

  • 9
    try:
      doSomething()
    except: 
      pass
    

    要么

    try:
      doSomething()
    except Exception: 
      pass
    

    不同的是,第一个也将捕获 KeyboardInterruptSystemExit 等类似的东西,它们直接来自 exceptions.BaseException ,而不是 exceptions.Exception .
    有关详情,请参阅文档

  • 54

    通常认为只捕获您感兴趣的错误的最佳做法 . 在 shutil.rmtree 的情况下,它可能是 OSError

    >>> shutil.rmtree("/fake/dir")
    Traceback (most recent call last):
        [...]
    OSError: [Errno 2] No such file or directory: '/fake/dir'
    

    如果您想静默忽略该错误,您可以:

    try:
        shutil.rmtree(path)
    except OSError:
        pass
    

    为什么?假设您(不知何故)意外地将函数传递给整数而不是字符串,例如:

    shutil.rmtree(2)
    

    它会给出错误"TypeError: coercing to Unicode: need string or buffer, int found" - 您可能不想忽略它,这可能很难调试 .

    如果你肯定想忽略所有错误,请 grab Exception 而不是一个简单的 except: 语句 . 再次,为什么?

    不指定异常会捕获每个异常,包括例如 sys.exit() 使用的 SystemExit 异常:

    >>> try:
    ...     sys.exit(1)
    ... except:
    ...     pass
    ... 
    >>>
    

    将此与以下内容进行比较,正确退出:

    >>> try:
    ...     sys.exit(1)
    ... except Exception:
    ...     pass
    ... 
    shell:~$
    

    如果你想编写更好的行为代码,OSError异常可以代表各种错误,但在上面的例子中我们只想忽略 Errno 2 ,所以我们可以更具体:

    try:
        shutil.rmtree(path)
    except OSError, e:
        if e.errno == 2:
            # suppress "No such file or directory" error
            pass
        else:
            # reraise the exception, as it's an unexpected error
            raise
    

    您也可以import errno并将 if 更改为 if e.errno == errno.ENOENT:

  • 108

    如果你只想尝试捕获而不处理异常,你如何在Python中做到这一点?

    这取决于“处理”的含义 .

    如果您想在不采取任何措施的情况下捕获它,您发布的代码将起作用 .

    如果你的意思是你想对异常采取行动而不停止异常上升,那么你想要这样的东西:

    try:
        do_something()
    except:
        handle_exception()
        raise  #re-raise the exact same exception that was thrown
    
  • 121

    首先,我引用杰克奥康纳的回答来自this thread . 引用的线程已关闭,所以我写在这里:

    “在Python 3.4中有一种新方法可以做到这一点:

    from contextlib import suppress
    
    with suppress(Exception):
        # your code
    

    这是添加它的提交:http://hg.python.org/cpython/rev/406b47c64480

    这里是作者Raymond Hettinger谈论这个以及各种其他Python热点:https://youtu.be/OSGv2VnC0go?t=43m23s

    我对此的补充是Python 2.7的等价物:

    from contextlib import contextmanager
    
    @contextmanager
    def ignored(*exceptions):
        try:
            yield
        except exceptions:
            pass
    

    然后你就像在Python 3.4中一样使用它:

    with ignored(Exception):
        # your code
    
  • 69

    为了完整性:

    >>> def divide(x, y):
    ...     try:
    ...         result = x / y
    ...     except ZeroDivisionError:
    ...         print "division by zero!"
    ...     else:
    ...         print "result is", result
    ...     finally:
    ...         print "executing finally clause"
    

    ......来自python tutorial .

    另请注意,您可以像这样捕获异常:

    >>> try:
    ...     this_fails()
    ... except ZeroDivisionError as detail:
    ...     print 'Handling run-time error:', detail
    
  • 0

    如何正确忽略例外?

    有几种方法可以做到这一点 .

    但是,示例的选择有一个简单的解决方案,不包括一般情况 .

    特定于示例:

    代替

    try:
        shutil.rmtree(path)
    except:
        pass
    

    做这个:

    shutil.rmtree(path, ignore_errors=True)
    

    这是 shutil.rmtree 特有的参数 . 您可以通过执行以下操作来查看有关它的帮助,您将看到它也可以允许错误功能 .

    >>> import shutil
    >>> help(shutil.rmtree)
    

    由于这只涵盖了示例的狭义情况,因此如果不存在这些关键字参数,我将进一步演示如何处理这个问题 .

    一般方法

    由于以上仅涵盖了示例的狭义情况,因此如果不存在这些关键字参数,我将进一步演示如何处理此问题 .

    Python 3.4中的新功能:

    您可以导入 suppress 上下文管理器:

    from contextlib import suppress
    

    但只能抑制最具体的异常:

    with suppress(FileNotFoundError):
        shutil.rmtree(path)
    

    你会默默地忽略 FileNotFoundError

    >>> with suppress(FileNotFoundError):
    ...     shutil.rmtree('bajkjbkdlsjfljsf')
    ... 
    >>>
    

    来自docs

    与完全抑制异常的任何其他机制一样,此上下文管理器应仅用于涵盖非常具体的错误,其中已知正确地继续执行程序是正确的 .

    请注意, suppressFileNotFoundError 仅在Python 3中可用 .

    如果您希望代码也在Python 2中工作,请参阅下一节:

    Python 2&3:

    当你只是想尝试/除了不处理异常时,你如何在Python中做到这一点?以下是正确的方法吗?尝试:
    shutil.rmtree(路径)
    除了 :
    通过

    对于Python 2兼容代码, pass 是获得无操作语句的正确方法 . 但是当你做一个 except: 时,这与做 except BaseException: (包括 GeneratorExitKeyboardInterruptSystemExit )相同,而且一般来说,你不想 grab 那些东西 .

    实际上,您应该尽可能详细地命名异常 .

    这是Python(2)exception hierarchy的一部分,正如您所看到的,如果您捕获更常见的异常,您可以隐藏您不期望的问题:

    BaseException
     +-- SystemExit
     +-- KeyboardInterrupt
     +-- GeneratorExit
     +-- Exception
          +-- StopIteration
          +-- StandardError
          |    +-- BufferError
          |    +-- ArithmeticError
          |    |    +-- FloatingPointError
          |    |    +-- OverflowError
          |    |    +-- ZeroDivisionError
          |    +-- AssertionError
          |    +-- AttributeError
          |    +-- EnvironmentError
          |    |    +-- IOError
          |    |    +-- OSError
          |    |         +-- WindowsError (Windows)
          |    |         +-- VMSError (VMS)
          |    +-- EOFError
    ... and so on
    

    你可能想在这里捕获一个OSError,也许你不关心的例外是没有目录 .

    我们可以从 errno 库中获取该特定错误编号,如果我们没有,则重新加载:

    import errno
    
    try:
        shutil.rmtree(path)
    except OSError as error:
        if error.errno == errno.ENOENT: # no such file or directory
            pass
        else: # we had an OSError we didn't expect, so reraise it
            raise
    

    注意,裸引发会引发原始异常,这可能是您在这种情况下想要的 . 写得更简洁,因为我们真的不需要在异常处理中明确地使用代码:

    try:
        shutil.rmtree(path)
    except OSError as error:
        if error.errno != errno.ENOENT: # no such file or directory
            raise
    
  • 40

    @当你只想尝试catch而不处理异常时,你是如何用Python做的?

    这将帮助您打印异常是:(即尝试catch而不处理异常并打印异常 . )

    import sys
    ....
    try:
        doSomething()
    except:
        print "Unexpected error:", sys.exc_info()[0]
    
    ...
    

    reg,Tilokchan

  • 884
    try:
          doSomething()
    except Exception: 
        pass
    else:
          stuffDoneIf()
          TryClauseSucceeds()
    

    FYI else子句可以在所有异常之后执行,并且只有在try中的代码不会导致异常时才会运行 .

  • 3

    在Python中,我们处理类似于其他语言的异常,但区别在于一些语法差异,例如,

    try:
        #Your code in which exception can occur
    except <here we can put in a particular exception name>:
        # We can call that exception here also, like ZeroDivisionError()
        # now your code
    # We can put in a finally block also
    finally:
        # Your code...
    
  • -1

    我需要忽略多个命令中的错误,并且fuckit做了诀窍

    import fuckit
    
    @fuckit
    def helper():
        print('before')
        1/0
        print('after1')
        1/0
        print('after2')
    
    helper()
    
  • 12

    只需 raise 相关的例外,就像这样:

    try:
         raise NameError('Joan')
     except NameError:
         print 'An exception just raised again by Joan!'
         raise
    

    就如此容易 . :)

    有关更多详细信息,请阅读此文档:https://docs.python.org/3.6/tutorial/errors.html

  • -1

    Handling an exception in Python:如果您有一些可能引发异常的可疑代码,您可以通过将可疑代码放在try:block中来保护您的程序 .

    try:
        # Your statements .............
    except ExceptionI:
        # Your statements.............
    except ExceptionII:
        # Your statements..............
    else:
       # Your statements
    

相关问题