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