raise ValueError('A very specific bad thing happened.')
不引发一般异常
避免引发一般异常。要捕获它,您必须捕获它的子类的所有其他更具体的异常。
问题1:隐藏bug
raise Exception('I know Python!') # Don't! If you catch, likely to hide bugs.
例如:
def demo_bad_catch():
try:
raise ValueError('Represents a hidden bug, do not catch this')
raise Exception('This is the exception you expect to handle')
except Exception as error:
print('Caught this error: ' + repr(error))
>>> demo_bad_catch()
Caught this error: ValueError('Represents a hidden bug, do not catch this',)
问题2:抓不到
更具体的捕获不会捕获一般异常:
def demo_no_catch():
try:
raise Exception('general exceptions not caught by specific handling')
except ValueError as e:
print('we will not catch exception: Exception')
>>> demo_no_catch()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in demo_no_catch
Exception: general exceptions not caught by specific handling
>>> catch_error_modify_message()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in catch_error_modify_message
File "<stdin>", line 2, in error
ValueError: oops! <modification>
def api_func(foo):
'''foo should be either 'baz' or 'bar'. returns something very useful.'''
if foo not in _ALLOWED_ARGS:
raise ValueError('{foo} wrong, use "baz" or "bar"'.format(foo=repr(foo)))
创建自己的错误类型
"I want to make an error on purpose, so that it would go into the except"
Use the most specific Exception constructor that semantically fits your issue。
在您的信息中具体说明,例如:
不引发一般异常
避免引发一般异常。要捕获它,您必须捕获它的子类的所有其他更具体的异常。
问题1:隐藏bug
例如:
问题2:抓不到
更具体的捕获不会捕获一般异常:
最佳实践:
raise
语句Instead, use the most specific Exception constructor that semantically fits your issue。
它还方便地允许将任意数量的参数传递给构造函数:
这些参数由异常对象的
args
属性访问。例如:印刷品
在Python 2.5中,一个实际的} and the original deprecation of args has been retracted 。
message
属性被添加到BaseException中,以鼓励用户对异常进行子类划分,并停止使用args
,但是the introduction of ^{最佳实践:
except
子句例如,在except子句中,您可能希望记录发生了特定类型的错误,然后重新引发。在保留堆栈跟踪的同时,最好的方法是使用一个raise语句。例如:
不要修改你的错误。。。但如果你坚持的话
您可以使用
sys.exc_info()
来保留stacktrace(和错误值),但这是更容易出错的方式,而且在Python 2和3之间存在兼容性问题,更愿意使用裸raise
来重新提升。为了解释,
sys.exc_info()
返回类型、值和回溯。这是Python2中的语法-注意这与Python3不兼容:
如果您愿意,可以修改新加薪的内容,例如为实例设置新参数:
我们在修改args的同时保留了整个回溯。请注意,这不是最佳实践,而且在Python 3中是无效语法(使保持兼容性变得更加困难)。
在Python 3中:
再次:避免手动操作回溯。它是less efficient而且更容易出错。如果你使用线程和
sys.exc_info
,你甚至可能得到错误的回溯(特别是如果你对控制流使用异常处理,我个人倾向于避免这种情况)Python 3,异常链接
在Python3中,可以链接异常,以保留跟踪:
注意:
不推荐的方法:
这些代码很容易隐藏,甚至可以进入生产代码。您想要引发异常,执行这些操作将引发异常,但不是预期的异常!
Valid in Python 2, but not in Python 3如下:
只有valid in much older versions of Python(2.4及更低版本),你可能仍然会看到人们在挑拨:
在所有现代版本中,这实际上会引发TypeError,因为您没有引发BaseException类型。如果您没有检查正确的异常,并且没有知道该问题的审阅者,那么它可能会投入生产。
示例用法
如果用户不正确使用我的API,我会提出异常警告:
创建自己的错误类型
您可以创建自己的错误类型,如果您想指出应用程序中的某些特定错误,只需在异常层次结构中为适当的点创建子类即可:
使用方法:
在Python3中,有4种不同的语法用于rasing异常:
如果使用
raise exception (args)
引发异常,则打印异常对象时将打印args
,如下例所示。没有任何参数的
raise
语句重新引发最后一个异常。 如果在捕获异常后需要执行某些操作,然后希望重新引发异常,则这非常有用。但是如果之前没有异常,raise
语句会引发TypeError
异常。此语句用于创建异常链,其中响应另一个异常而引发的异常可以包含原始异常的详细信息,如下例所示。
输出:
再也没有比这更像Python了:
如果您想了解更多信息,请参见python的the raise statement docs。
相关问题 更多 >
编程相关推荐