python 3.5中的回溯

时间:2016-02-22 03:22:19

标签: python exception exception-handling

为了优雅地处理Python 3.5中的错误,我使用以下代码:

    except:
        exc_type, exc_value, exc_traceback = sys.exc_info()
        # print("Unable to write feed_item in database")
        # print(feeditem_insert_data)
        error_insert_data = (
            prog_name, 'Unable to populate item for (feed id,ref_feed_id) ('
                       + str(feed_id) +',' + str(ref_feed_id) + ') in feed_item table'
            , str(exc_type), str(exc_value), repr(traceback.format_tb(exc_traceback)), datetime.datetime.now()
        )
        cur_error_log.execute(error_insert_stmt,error_insert_data)
        continue

在我的程序中的许多地方添加此代码后,我观察到奇怪的行为,因为在程序运行中长时间在相同数据上运行的行为与程序运行短路不同。我无法确切地说在添加上面的代码后出现了这种行为。

但是我记得在某个地方读过如果我使用追溯而不是手动释放内存。

如果我上面的模块在技术上是正确的,或者需要采取一些措施来避免问题,请提供建议。

1 个答案:

答案 0 :(得分:3)

Python 3中关于异常的主要变化是,不再需要使用sys.exc_info来获取回溯。它现在可以作为异常对象的__traceback__属性使用(这是可能的,因为Python 3中的所有异常都必须从基类Exception类继承,而旧版本的Python 2允许将任何内容视为除外)。

因此,您可以使用except替换except Exception as e:代码的前两行,然后在错误中使用type(e)ee.__traceback__报告代码,而不是您从sys.exc_info获得的值。

将回溯作为异常的属性可能会对内存使用产生一些不利影响。具体来说,它在当前执行帧和异常之间创建一个引用循环。框架引用异常(如果已将其绑定到局部变量),该异常通过其属性引用回溯,并且回溯引用该框架。循环意味着当参考计数系统超出范围时,内存不能立即回收。相反,它必须依赖循环垃圾收集器,它可能很慢地回收内存,甚至永远不会绕过它(你可以完全关闭它)。

为了减少此问题的影响,Python将自动删除在其块结尾处由except ExceptionType as e语句创建的异常变量。如果您使用其他名称创建对异常的引用,则可能需要自行清理它们,以避免记忆延迟时间超过您的需要。

因此,如果您确实遇到与异常相关的内存问题,请尝试在del exc_value, exc_traceback块的末尾添加try,就在continue之前。或者,切换到我上面描述的except Exception as e语法,并且将自动从本地命名空间中删除e(或您使用的任何名称)。