为了优雅地处理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
在我的程序中的许多地方添加此代码后,我观察到奇怪的行为,因为在程序运行中长时间在相同数据上运行的行为与程序运行短路不同。我无法确切地说在添加上面的代码后出现了这种行为。
但是我记得在某个地方读过如果我使用追溯而不是手动释放内存。
如果我上面的模块在技术上是正确的,或者需要采取一些措施来避免问题,请提供建议。
答案 0 :(得分:3)
Python 3中关于异常的主要变化是,不再需要使用sys.exc_info
来获取回溯。它现在可以作为异常对象的__traceback__
属性使用(这是可能的,因为Python 3中的所有异常都必须从基类Exception
类继承,而旧版本的Python 2允许将任何内容视为除外)。
因此,您可以使用except
替换except Exception as e:
代码的前两行,然后在错误中使用type(e)
,e
和e.__traceback__
报告代码,而不是您从sys.exc_info
获得的值。
将回溯作为异常的属性可能会对内存使用产生一些不利影响。具体来说,它在当前执行帧和异常之间创建一个引用循环。框架引用异常(如果已将其绑定到局部变量),该异常通过其属性引用回溯,并且回溯引用该框架。循环意味着当参考计数系统超出范围时,内存不能立即回收。相反,它必须依赖循环垃圾收集器,它可能很慢地回收内存,甚至永远不会绕过它(你可以完全关闭它)。
为了减少此问题的影响,Python将自动删除在其块结尾处由except ExceptionType as e
语句创建的异常变量。如果您使用其他名称创建对异常的引用,则可能需要自行清理它们,以避免记忆延迟时间超过您的需要。
因此,如果您确实遇到与异常相关的内存问题,请尝试在del exc_value, exc_traceback
块的末尾添加try
,就在continue
之前。或者,切换到我上面描述的except Exception as e
语法,并且将自动从本地命名空间中删除e
(或您使用的任何名称)。