python 忽略异常_关于python:如何正确地忽略异常

当您只是想尝试—除非不处理异常,否则如何在Python中进行尝试?

下面的方法正确吗?

try:

shutil.rmtree(path)

except:

pass

奇怪的是直到现在还没有人提到它(我在我的答案中提到了),但是对于这个特定的函数,您只需要执行shutil.rmtree(path, ignore_errors=True)。但是,这并不适用于大多数函数。

在考虑忽略异常时,请务必阅读:为什么"except: pass"是一个糟糕的编程实践?

想象一下在现实生活中这样做。尝试:get_cash('$1000')除了:pass # meh,它可能会很好

try:

doSomething()

except:

pass

try:

doSomething()

except Exception:

pass

不同之处在于,第一个捕获器还将捕获KeyboardInterrupt、SystemExit之类的对象,这些对象直接派生自exceptions.BaseException,而不是exceptions.Exception。详见文档:试着声明本;http://docs.python.org/reference/compound_stmts.html#try异常本;http://docs.python.org/library/exceptions

注意StopIteration和Warning都继承自Exception。根据您的需要,您可能希望从standard derror继承。

这两个都是"正常的"异常,所以没有问题。

这是正确的,但是如果不小心,您可能会遇到一些细微的bug(特别是当您正在执行一些操作而不是传递StopIteration时)。

-1, try: shuti.rmtree(...) except: pass将粗略地抑制任何错误(即使您拼错了shutil导致了一个NameError) -至少做了except OSError:

这个答案虽然提供了丰富的信息,但漏掉了一个关键信息——您永远不应该以这种方式捕获异常。相反,您应该总是尝试只捕获您所关心的异常,否则,当您在寻找由通用的"except"隐藏的小错误时,您将会做噩梦。有关更多信息,请参见dbr的回答。(我知道这不是最初的问题——但是任何想要了解这一点的人都可以使用您的代码片段并按原样使用)

通常认为最好的实践是只捕获您感兴趣的错误。在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: cocing 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,所以我们可以更具体:

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:

When you just want to do a try catch without handling the exception, how do you do it in Python?

这取决于你所说的"处理"是什么意思。

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

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

try:

do_something()

except:

handle_exception()

raise  #re-raise the exact same exception that was thrown

首先,我从这篇文章中引用了杰克·奥康纳的答案。被引用的线程被关闭,所以我写在这里:

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

from contextlib import suppress

with suppress(Exception):

# your code

下面是添加它的commit: 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

完整性:

>>> 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教程。

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

>>> try:

...     this_fails()

... except ZeroDivisionError as detail:

...     print 'Handling run-time error:', detail

How to properly ignore Exceptions?

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

然而,示例的选择有一个简单的解决方案,不涉及一般情况。特定于示例:

而不是

try:

shutil.rmtree(path)

except:

pass

这样做:

shutil.rmtree(path, ignore_errors=True)

这是一个特定于shutil.rmtree的参数。通过执行以下操作,您可以看到对它的帮助,您还将看到它还允许对错误执行功能。

>>> import shutil

>>> help(shutil.rmtree)

由于这只涵盖了示例的有限情况,所以我将进一步演示如何处理不存在这些关键字参数的情况。

一般方法

由于上面只讨论了示例的有限情况,所以我将进一步演示如何处理不存在这些关键字参数的情况。New in python3.4:

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

from contextlib import suppress

但只抑制最特殊的例外:

with suppress(FileNotFoundError):

shutil.rmtree(path)

您将无声地忽略一个FileNotFoundError:

>>> with suppress(FileNotFoundError):

...     shutil.rmtree('bajkjbkdlsjfljsf')

...

>>>

从文档:

As with any other mechanism that completely suppresses exceptions,

this context manager should be used only to cover very specific errors

where silently continuing with program execution is known to be the

right thing to do.

注意,suppress和FileNotFoundError只在python3中可用。

如果您希望您的代码也能在python2中工作,请参见下一节:

Python 2,3:

When you just want to do a try/except without handling the exception,

how do you do it in Python?

Is the following the right way to do it?

try :

shutil.rmtree ( path )

except :

pass

对于Python 2兼容的代码,pass是使语句成为no-op的正确方法。但是当您执行一个简单的except:时,这与执行包含GeneratorExit、KeyboardInterrupt和SystemExit的except BaseException:是一样的,而且通常您不想捕获这些东西。

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

下面是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

注意,裸升会引发原始异常,在本例中,这可能正是您想要的。写得更简洁,因为我们真的不需要显式的pass与代码在异常处理:

try:

shutil.rmtree(path)

except OSError as error:

if error.errno != errno.ENOENT: # no such file or directory

raise

When you just want to do a try catch without handling the exception,

how do you do it in Python?

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

import sys

try:

doSomething()

except:

print"Unexpected error:", sys.exc_info()[0]

try:

doSomething()

except Exception:

pass

else:

stuffDoneIf()

TryClauseSucceeds()

仅供参考,else子句可以放在所有异常之后,并且只有在try中的代码没有引起异常时才会运行。

最后,在这个上下文中很好地解释了else。并添加finally将始终在任何(或没有异常)之后运行。

在Python中,我们处理与其他语言类似的异常,但是不同之处在于一些语法上的不同,例如,

try:

#Your code in which exception can occur

except :

# We can call that exception here also, like ZeroDivisionError()

# now your code

# We can put in a finally block also

finally:

# Your code...

我需要忽略多个命令中的错误,而fuckit做到了

import fuckit

@fuckit

def helper():

print('before')

1/0

print('after1')

1/0

print('after2')

helper()

"这个模块就像暴力:如果它不起作用,你只需要更多。"

简单地提出相关的异常,就像这样:

try:

raise NameError('Joan')

except NameError:

print 'An exception just raised again by Joan!'

raise

就这么简单。:)

要了解更多细节,请阅读本文:https://docs.python.org/3.6/tutorial/errors.html

为什么不直接使用John而不是raise NameError('Joan')(仅当John没有定义时)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值