除了定义函数外,我应该如何使用try ...

时间:2010-04-01 12:04:26

标签: python exception function

我发现当我不需要使用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来获取它们。 我的问题是,在定义函数时到处使用它是一个好习惯吗?如果不是有任何原则吗?帮助将不胜感激!

此致

4 个答案:

答案 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)

您必须在多个目标之间找到平衡点:

  1. 应用程序应自行从尽可能多的错误中恢复。

  2. 应用程序应报告所有不可恢复的错误,并详细说明问题的原因。

  3. 错误可能发生在任何地方,但您不希望使用所有错误处理代码污染您的代码。

  4. 应用程序不应崩溃

  5. 要解决#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