Sha*_*ang 200 python exception
我有一个主程序调用的函数:
try:
someFunction()
except:
print "exception happened!"
Run Code Online (Sandbox Code Playgroud)
但是在函数执行过程中它会引发异常,因此会跳转到该except
部分.
我怎样才能确切地看到发生了什么someFunction()
导致异常发生?
Lau*_*low 339
其他答案都指出你不应该抓住一般的例外,但似乎没有人想告诉你为什么,这对于理解何时可以打破"规则"至关重要.这是一个解释.基本上,这是你不隐藏:
因此,只要您注意不做这些事情,就可以捕获一般异常.例如,您可以通过其他方式向用户提供有关异常的信息,例如:
那么如何捕获泛型异常呢?有几种方法.如果您只想要异常对象,请执行以下操作:
try:
someFunction()
except Exception as ex:
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
message = template.format(type(ex).__name__, ex.args)
print message
Run Code Online (Sandbox Code Playgroud)
请确保 message
被带到用户的注意力在一个难以错过的方式!如上所示,如果将消息隐藏在许多其他消息中,则打印它可能是不够的.没有引起用户的注意就等于吞下所有异常,如果有一个印象,你应该在阅读了这个页面上的答案后离开,这就是这不是一件好事.使用raise
语句结束except块将通过透明地重新捕获已捕获的异常来解决问题.
上述之间的区别和使用except:
不带任何参数的区别是双重的:
except:
不会给你检查的异常对象SystemExit
,KeyboardInterrupt
并GeneratorExit
没有被上面的代码捕获,这通常是你想要的.请参阅异常层次结构.如果你也想要获得相同的堆栈跟踪,如果你没有捕获异常,你可以像这样(仍然在except子句中):
import traceback
print traceback.format_exc()
Run Code Online (Sandbox Code Playgroud)
如果您使用该logging
模块,您可以将异常打印到日志(以及消息),如下所示:
import logging
log = logging.getLogger()
log.exception("Message for you, sir!")
Run Code Online (Sandbox Code Playgroud)
如果你想深入挖掘并检查堆栈,查看变量等,请使用except块内的模块post_mortem
函数pdb
:
import pdb
pdb.post_mortem()
Run Code Online (Sandbox Code Playgroud)
我发现这最后一种方法在追捕bug时非常宝贵.
Ale*_*lex 48
获取异常对象所属的类的名称:
e.__class__.__name__
Run Code Online (Sandbox Code Playgroud)
并使用print_exc()函数也将打印堆栈跟踪,这是任何错误消息的基本信息.
像这样:
from traceback import print_exc
class CustomException(Exception): pass
try:
raise CustomException("hi")
except Exception, e:
print 'type is:', e.__class__.__name__
print_exc()
# print "exception happened!"
Run Code Online (Sandbox Code Playgroud)
你会得到这样的输出:
type is: CustomException
Traceback (most recent call last):
File "exc.py", line 7, in <module>
raise CustomException("hi")
CustomException: hi
Run Code Online (Sandbox Code Playgroud)
在打印和分析之后,代码可以决定不处理异常并只执行raise
:
from traceback import print_exc
class CustomException(Exception): pass
def calculate():
raise CustomException("hi")
try:
calculate()
except Exception, e:
if e.__class__ == CustomException:
print 'special case of', e.__class__.__name__, 'not interfering'
raise
print "handling exception"
Run Code Online (Sandbox Code Playgroud)
输出:
special case of CustomException not interfering
Run Code Online (Sandbox Code Playgroud)
翻译打印异常:
Traceback (most recent call last):
File "test.py", line 9, in <module>
calculate()
File "test.py", line 6, in calculate
raise CustomException("hi")
__main__.CustomException: hi
Run Code Online (Sandbox Code Playgroud)
在raise
原始异常继续向上传播调用堆栈之后.(注意可能的陷阱)如果你引发新的异常,它会篡改新的(更短的)堆栈跟踪.
from traceback import print_exc
class CustomException(Exception): pass
def calculate():
raise CustomException("hi")
try:
calculate()
except Exception, e:
if e.__class__ == CustomException:
print 'special case of', e.__class__.__name__, 'not interfering'
#raise CustomException(e.message)
raise e
print "handling exception"
Run Code Online (Sandbox Code Playgroud)
输出:
special case of CustomException not interfering
Traceback (most recent call last):
File "test.py", line 13, in <module>
raise CustomException(e.message)
__main__.CustomException: hi
Run Code Online (Sandbox Code Playgroud)
请注意traceback如何不包含calculate()
来自9
原始异常原点的行的函数e
.
hoc*_*chl 13
你通常不应该抓住所有可能的例外情况,try: ... except
因为它过于宽泛.抓住那些因任何原因而发生的事情.如果你真的必须,例如,如果你想在调试时找到更多关于某些问题的信息,你应该这样做
try:
...
except Exception as ex:
print ex # do whatever you want for debugging.
raise # re-raise exception.
Run Code Online (Sandbox Code Playgroud)
Chr*_*ris 10
这些答案对于调试来说很好,但是对于以编程方式测试异常来说,isinstance(e, SomeException)
可以很方便,因为它测试了SomeException
太的子类,因此您可以创建适用于异常层次结构的功能。
除非somefunction
是一个非常糟糕的编码遗留函数,否则你不应该需要你所要求的.
使用multiple except
子句以不同的方式处理不同的异常:
try:
someFunction()
except ValueError:
# do something
except ZeroDivision:
# do something else
Run Code Online (Sandbox Code Playgroud)
重点是你不应该捕获泛型异常,而只捕获你需要的异常.我确定你不想影响意外的错误或错误.
大多数答案都指向except (…) as (…):
语法(这是正确的)但同时没有人想谈论大象在其中sys.exc_info()
起作用的房间里的大象.从文档的SYS模块(重点煤矿):
此函数返回三个值的元组,这些值提供有关当前正在处理的异常的信息.
(...)
如果堆栈中的任何地方都没有处理异常,则返回包含三个None值的元组.否则,返回的值是(type,value,traceback).它们的含义是:type获取正在处理的异常的类型(BaseException的子类); value获取异常实例(异常类型的实例); traceback获取一个回溯对象(请参阅参考手册),该对象将调用堆栈封装在最初发生异常的位置.
我认为这sys.exc_info()
可以被视为对原始问题的最直接的答案:我怎么知道发生了什么类型的异常?
尝试:someFunction()除了Exception,exc:
#this is how you get the type
excType = exc.__class__.__name__
#here we are printing out information about the Exception
print 'exception type', excType
print 'exception msg', str(exc)
#It's easy to reraise an exception with more information added to it
msg = 'there was a problem with someFunction'
raise Exception(msg + 'because of %s: %s' % (excType, exc))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
161600 次 |
最近记录: |