保存 python 异常以便稍后重新引发,同时保持回溯

问题描述 投票:0回答:0

我目前正在编写装饰器来将结果缓存在磁盘上。我希望无论 f(x) 是否已存储,f(x) 都会给出相同的结果,即使 f(x) 引发异常。即,当 f 引发异常时加载 f(x) 的存储结果应该引发相同的异常(稍微修改指示上下文)。

我已经成功编写了 f 存储在内存中的代码,但是在使用 pickle (将用于保存在磁盘上)时它不起作用。这是完整的演示代码。请注意,当异常经过 pickle 后,它如何不输出回溯。

import pickle, traceback, sys import logging logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) def buggy(x): raise ValueError("my error") def f(x): if x < 10: return buggy(x) else: return x+2 class DelayedException(Exception): def __init__(self, s): super().__init__(s) for val, method in [ (0, "no_cache"), (100, "no_cache"), #direct function call (what we want to imitate) (0, "memory_cached"), (100, "memory_cached"), #reraising later without saving/loading (currently good result) (0, "pickled_cache"), (100, "pickled_cache") #reraising later with saving/loading in between ]: print("\n\n") try: logger.info(f"val = {val}, method={method}") if method=="no_cache": res = f(val) else: try: res = f(val) except BaseException as e: # The code can be changed here try: #Not very readable technique to append this exception in the exception stack. #I'm very open to samething better raise DelayedException(f"Error in {f.__name__}({val})") except DelayedException as d: try: raise e from d except BaseException as final: res = final if method=="pickled_cache": #for simplicity we use a string instead of a file for demo purposes res = pickle.dumps(res) res = pickle.loads(res) if isinstance(res, BaseException): # The code also can be changed here raise res logger.info(f"ok, res = {res}") except: logger.error(traceback.format_exc())
关于如何让它发挥作用有什么想法吗?代码中的注释应该让我知道我想在哪里更改内容。
另外,我已经研究过 

tblib,但我不清楚如何将它用于我的目的。也许有人知道如何调整它的一些内部运作来适应我的问题?

python exception pickle traceback
© www.soinside.com 2019 - 2024. All rights reserved.