我发现当我不需要使用try..except
这个问题时我感到很困惑。最近几天它几乎用在我定义的每个函数中,我认为这可能是一个不好的做法。例如:
class mongodb(object):
def getRecords(self,tname,conditions=''):
try:
col = eval("self.db.%s" %tname)
recs = col.find(condition)
return recs
except Exception,e:
#here make some error log with e.message
我的想法是,到处可能会出现异常,我必须使用try
来获取它们。
我的问题是,在定义函数时到处使用它是一个好习惯吗?如果不是有任何原则吗?帮助将不胜感激!
此致
答案 0 :(得分:5)
这(非常广泛地捕捉所有可能的例外)确实被认为是不好的做法。你将掩盖异常的真正原因。
仅捕获“明确命名的”类型的异常(您希望发生和,您可以/将会优雅地处理)。让剩下的(意想不到的)冒泡吧。
您可以通过覆盖sys.excepthook
:
import sys
import traceback
# ...
def my_uncaught_exception_hook(exc_type, exc_value, exc_traceback):
msg_exc = "".join( \
traceback.format_exception(exc_type, exc_value, exc_traceback) )
# ... log here...
sys.excepthook = my_uncaught_exception_hook # our uncaught exception hook
答案 1 :(得分:5)
这可能不是最好的事情。异常的全部意义在于,您可以将它们捕获到与其引发的不同的级别上。最好在有足够信息的地方处理它们,以便对它们有用(这非常依赖于应用程序和上下文)。
例如下面的代码可以抛出IOError(“[Errno 2]没有这样的文件或目录”):
def read_data(filename):
return open(filename).read()
在该函数中,您没有足够的信息来处理它,但在实际使用此函数的地方,如果出现此类异常,您可能会决定尝试使用不同的文件名或向用户显示错误,或者别的东西:
try:
data = read_data('data-file.txt')
except IOError:
data = read_data('another-data-file.txt')
# or
show_error_message("Data file was not found.")
# or something else
答案 2 :(得分:4)
您必须在多个目标之间找到平衡点:
应用程序应自行从尽可能多的错误中恢复。
应用程序应报告所有不可恢复的错误,并详细说明问题的原因。
错误可能发生在任何地方,但您不希望使用所有错误处理代码污染您的代码。
应用程序不应崩溃
要解决#3,您可以使用exception hook。所有未处理的异常都将导致当前事务中止。在最高级别捕获它们,回滚事务(因此数据库不会变得不一致)并再次抛出它们或吞下它们(因此应用程序不会崩溃)。您应该使用decorators for this。这解决了#4和#1。
#2的解决方案是经验。您将及时了解解决问题所需的信息。发生错误时,困难的部分仍然是信息。一种解决方案是在低级方法中添加调试日志记录调用。
另一个解决方案是每个线程的字典,您可以在其中存储一些位,并在发生错误时将其转储。
答案 3 :(得分:1)
另一种选择是在try中包装大部分代码:except :(例如在Web应用程序中,一个特定的GUI页面)然后使用sys.exc_info()打印出错误以及堆栈的位置它发生了
import sys
import traceback
try:
#some buggy code
x = ??
except:
print sys.exc_info()[0] #prints the exception class
print sys.exc_info()[1] #prints the error message
print repr(traceback.format_tb(sys.exc_info()[2])) #prints the stack