873

当你只想做一个 try-except 而不处理异常时,你如何在 Python 中做到这一点?

以下是正确的方法吗?

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

12 回答 12

1151
try:
    doSomething()
except: 
    pass

或者

try:
    doSomething()
except Exception: 
    pass

不同之处在于第一个也将捕获KeyboardInterruptSystemExit以及类似的东西,它们直接来自exceptions.BaseException,而不是exceptions.Exception

有关详细信息,请参阅文档:

于 2009-04-08T16:25:10.150 回答
158

仅捕获您感兴趣的错误通常被认为是最佳实践。在这种情况下,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” ——你可能不想忽略它,这可能很难调试。

如果您绝对想忽略所有错误,请捕获Exception而不是简单的except:语句。再说一遍,为什么?

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

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

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

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

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

import errno

try:
    shutil.rmtree(path)
except OSError as e:
    if e.errno != errno.ENOENT:
        # ignore "No such file or directory", but re-raise other errors
        raise
于 2009-04-09T21:48:05.330 回答
118

当你只想做一个 try catch 而不处理异常时,你如何在 Python 中做到这一点?

这取决于您所说的“处理”是什么意思。

如果您打算在不采取任何行动的情况下捕获它,那么您发布的代码将起作用。

如果你的意思是你想对异常采取行动而不阻止异常进入堆栈,那么你需要这样的东西:

try:
    do_something()
except:
    handle_exception()
    raise  #re-raise the exact same exception that was thrown
于 2009-04-08T16:32:32.630 回答
107

首先,我从这个线程中引用 Jack o'Connor 的答案。引用的线程已关闭,所以我在这里写:

“在 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
于 2013-09-07T20:55:51.540 回答
59

为了完整性:

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

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

>>> try:
...     this_fails()
... except ZeroDivisionError as err:
...     print("Handling run-time error:", err)

...并像这样重新引发异常:

>>> try:
...     raise NameError('HiThere')
... except NameError:
...     print('An exception flew by!')
...     raise

此外,可以将多种异常类型作为带括号的元组处理:

try:
    i_might_fail()
except (ValueError, TypeError) as ex:
    print('I failed with: ', ex)

...或作为单独的 except 子句:

try:
    i_might_fail()
except ValueError:
    print('handling a ValueError...')
except TypeError:
    print('handling a TypeError...')

...请参阅python 教程

于 2010-03-05T23:02:39.080 回答
46

如何正确忽略异常?

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

但是,示例的选择有一个简单的解决方案,不涵盖一般情况。

具体到例子:

代替

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)

您将默默地忽略 a FileNotFoundError

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

文档

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

请注意,suppressandFileNotFoundError仅在 Python 3 中可用。

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

蟒蛇 2 和 3:

当你只想做一个 try/except 而不处理异常时,你如何在 Python 中做到这一点?

以下是正确的方法吗?

try :
    shutil.rmtree ( path )
except :
    pass

对于 Python 2 兼容代码,pass正确的方法是拥有一个无操作的语句。但是当你做一个 bareexcept:时,这与做except BaseException:which includes GeneratorExit, KeyboardInterrupt, and是一样的SystemExit,而且一般来说,你不想抓住那些东西。

事实上,您应该尽可能具体地命名异常。

这是 Python (2)异常层次结构的一部分,如您所见,如果您捕获了更一般的异常,您可以隐藏您没有预料到的问题:

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 

请注意,一个简单的 raise 会引发原始异常,这可能是您在这种情况下想要的。写得更简洁,因为我们真的不需要pass在异常处理中显式地使用代码:

try:
    shutil.rmtree(path)
except OSError as error:
    if error.errno != errno.ENOENT: # no such file or directory
        raise 
于 2015-01-22T04:42:53.773 回答
11
try:
      doSomething()
except Exception: 
    pass
else:
      stuffDoneIf()
      TryClauseSucceeds()

仅供参考,else 子句可以跟踪所有异常,并且只有在 try 中的代码不会导致异常时才会运行。

于 2009-11-19T22:35:58.803 回答
11

当你只想做一个 try catch 而不处理异常时,你如何在 Python 中做到这一点?

这将帮助您打印异常是什么:(即在不处理异常的情况下尝试捕获并打印异常。)

import sys
try:
    doSomething()
except:
    print "Unexpected error:", sys.exc_info()[0]
于 2011-10-12T05:36:30.833 回答
9

我需要忽略多个命令中的错误,而他妈的成功了

import fuckit

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

helper()
于 2018-12-01T21:23:26.763 回答
4

在 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...
于 2010-11-18T10:27:56.803 回答
1

好吧,这不是 try-except 而是另一种处理异常的方法,如果你喜欢面向对象编程的话:

class MyExceptionHandler:

    def __enter__(self):
        ... # Do whatever when "with" block is started
        return self

    def __exit__(self, exc_type, exc_value, tb):
        return True

然后到实际代码:

with MyExceptionHandler():
     ... # Code that may or may not raise an exception
     shutil.rmtree(path)

这是如何工作的?

  • __enter__进入with块时运行。
  • __exit__退出with块 时运行
    • 这应该返回True以使可能的异常保持沉默。
    • 这应该返回None(或被认为是 False 的东西)以不使潜在的异常静音。
    • 异常类型、实际异常及其回溯作为(位置)参数传递。您可以使用这些来确定要做什么。

最后一点,更喜欢 try-except。如果您需要比平时更多的抽象,这可能很有用。

于 2021-10-28T06:44:19.903 回答
-5

我通常只是这样做:

try:
    doSomething()
except:
    _ = ""
于 2020-01-26T15:25:32.140 回答