我已经找到了解决办法,但仍想知道答案。
答案 0 :(得分:20)
回溯保存对当前线程上调用的每个函数/方法的堆栈帧的引用,从最上面的帧到下一个引发错误的点。每个堆栈帧还保存对在调用堆栈中的每个函数时有效的局部变量和全局变量的引用。
由于pickle无法知道要序列化什么以及忽略什么,如果你能够挑选回溯,你最终会挑选整个应用程序状态的移动快照:当pickle运行时,其他线程可能修改共享变量的值。
一种解决方案是创建一个可选对象来遍历回溯并仅提取您需要保存的信息。
答案 1 :(得分:2)
您可以使用tblib
try:
1 / 0
except Exception as e:
raise Exception("foo") from e
except Exception as e:
s = pickle.dumps(e)
raise pickle.loads(s)
答案 2 :(得分:0)
我猜您有兴趣保存每个帧的完整调用上下文(追溯 + 全局 + 本地)。
这对于确定两个不同调用上下文中相同函数的行为差异,或构建您自己的高级工具来处理,显示或比较这些回溯非常有用。
问题是 pickl 不知道如何序列化可能位于 locals 或 globals 中的所有类型的对象。
我猜你可以构建自己的对象并保存它,过滤掉所有那些不是 picklabe 的对象。此代码可作为基础:
import sys, traceback
def print_exc_plus():
"""
Print the usual traceback information, followed by a listing of all the
local variables in each frame.
"""
tb = sys.exc_info()[2]
while 1:
if not tb.tb_next:
break
tb = tb.tb_next
stack = []
f = tb.tb_frame
while f:
stack.append(f)
f = f.f_back
stack.reverse()
traceback.print_exc()
print "Locals by frame, innermost last"
for frame in stack:
print
print "Frame %s in %s at line %s" % (frame.f_code.co_name,
frame.f_code.co_filename,
frame.f_lineno)
for key, value in frame.f_locals.items():
print "\t%20s = " % key,
#We have to be careful not to cause a new error in our error
#printer! Calling str() on an unknown object could cause an
#error we don't want.
try:
print value
except:
print "<ERROR WHILE PRINTING VALUE>"
但是不是打印对象,而是可以将它们添加到具有您自己的可选表示的列表中( json 或 yml 格式可能更好)。
也许您想要加载所有这些调用上下文,以便为您的函数重现相同的情况,而无需运行生成它的复杂工作流。我不知道是否可以这样做(因为内存引用),但在这种情况下,您需要从格式中反序列化它。