简体   繁体   English

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

[英]How should I use try…except while defining a function?

I find I've been confused by the problem that when I needn't to use try..except .For last few days it was used in almost every function I defined which I think maybe a bad practice.For example: 我发现当我不需要使用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

What I thought is ,exceptions may be raised everywhere and I have to use try to get them. 我的想法是,到处可能会出现异常,我必须try使用它们。 And my question is,is it a good practice to use it everywhere when defining functions?If not are there any principles for it?Help would be appreciated! 我的问题是,在定义函数时到处使用它是一个好习惯吗?如果不是有任何原则吗?帮助将不胜感激!

Regards 问候

This (catching all possible exceptions very broadly) is indeed considered bad practice. 这(非常广泛地捕捉所有可能的例外)确实被认为是不好的做法。 You'll mask the real reason for the exception. 你将掩盖异常的真正原因。

Catch only ' explicitely named ' types of exceptions (which you expect to happen and you can/will handle gracefully). 仅捕获' 明确命名 '的异常类型(您希望发生这种异常, 并且您可以/将优雅地处理)。 Let the rest (unexpected ones) bubble as they should. 让其他人(意想不到的人)按照他们应该的方式冒泡。

You can log these (uncaught) exceptions (globally) by overriding sys.excepthook : 您可以通过覆盖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

That may not be the best thing to do. 这可能不是最好的事情。 Whole point of exceptions is that you can catch them on very different level than it's raised. 异常的全部意义在于,您可以将它们捕获到与其引发的不同的级别上。 It's best to handle them in the place where you have enough information to make something useful with them (that is very application and context dependent). 最好在有足够信息的地方处理它们,以便对它们有用(这非常依赖于应用程序和上下文)。

For example code below can throw IOError("[Errno 2] No such file or directory"): 例如,下面的代码可以抛出IOError(“[Errno 2]没有这样的文件或目录”):

def read_data(filename):
    return open(filename).read()

In that function you don't have enough information to do something with it, but in place where you actually using this function, in case of such exception, you may decide to try different filename or display error to the user, or something else: 在该函数中,您没有足够的信息来处理它,但是在实际使用此函数的地方,如果出现此类异常,您可能会决定尝试使用不同的文件名或向用户显示错误,或者其他内容:

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

You must find a balance between several goals: 你必须在几个目标之间找到平衡点:

  1. An application should recover from as many errors as possible by itself. 应用程序应自行从尽可能多的错误中恢复。

  2. An application should report all unrecoverable errors with enough detail to fix the cause of the problem. 应用程序应报告所有不可恢复的错误,并提供足够的详细信息以解决问题的原因。

  3. Errors can happen everywhere but you don't want to pollute your code with all the error handling code. 错误可能发生在任何地方,但您不希望使用所有错误处理代码污染您的代码。

  4. Applications shouldn't crash 应用程序不应该崩溃

To solve #3, you can use an exception hook . 要解决#3,您可以使用异常挂钩 All unhandled exceptions will cause the current transaction to abort. 所有未处理的异常都将导致当前事务中止。 Catch them at the highest level, roll back the transaction (so the database doesn't become inconsistent) and either throw them again or swallow them (so the app doesn't crash). 在最高级别捕获它们,回滚事务(因此数据库不会变得不一致)并再次抛出它们或吞下它们(因此应用程序不会崩溃)。 You should use decorators for this . 你应该使用装饰器 This solves #4 and #1. 这解决了#4和#1。

The solution for #2 is experience. #2的解决方案是经验。 You will learn with time what information you need to solve problems. 您将及时了解解决问题所需的信息。 The hard part is to still have the information when an error happens. 发生错误时,困难的部分仍然是信息。 One solution is to add debug logging calls in the low level methods. 一种解决方案是在低级方法中添加调试日志记录调用。

Another solution is a dictionary per thread in which you can store some bits and which you dump when an error happens. 另一个解决方案是每个线程的字典,您可以在其中存储一些位,并在发生错误时转储。

another option is to wrap a large section of code in a try: except: (for instance in a web application, one specific GUI page) and then use sys.exc_info() to print out the error and also the stack where it occurred 另一种选择是在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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM