Python例外安全泡菜使用

时间:2015-10-23 16:50:25

标签: python python-2.7 exception-handling

背景

我继承了一个包含大量try ... except:子句的代码库。他们中的大多数都太宽泛了,调试很麻烦。我一直在进行并将每个更改为最合理的形式,这通常涉及删除它或指定例外。

问题

但我对这一点感到有点难过:

try:
    with open(self.session_filename, "rb") as f:
        data = cPickle.loads(zlib.decompress(f.read()))
except:
    # we didn't need your file anyway!
    return

我想具体处理这些例外,但Python docs on Pickle说:

  

异常pickle.UnpicklingError

     

当出现问题时,会引发此异常   宾语。请注意,在期间也可能会引发其他异常   unpickling,包括(但不一定限于) AttributeError,   EOFErrorImportErrorIndexError

翻译:该方法可能会抛出任何东西!

显然,它可以引发任意异常,这使得特别难以处理它们。

我如何才能最合理地处理这种情况,并牢记以下目标:

  1. 我希望捕获因文件名错误或其他操作系统问题或格式错误而导致的所有异常。
  2. 我不想过于宽泛,从而隐藏其他问题。
  3. 我不想阅读实现并尝试解析所有不同的潜在异常。这将取决于实现,可能会因更新而失败,并且需要花费大量时间。
  4. 可能并非所有人都能实现。

2 个答案:

答案 0 :(得分:4)

将异常分解为多个处理程序可能是您想要的,如果您需要,可以使用它。

try:
    with open(self.session_filename, "rb") as f:
         data = cPickle.loads(zlib.decompress(f.read()))
except pickle.UnpicklingError as e:
    # normal, somewhat expected
    continue
except (AttributeError,  EOFError, ImportError, IndexError) as e:
    # secondary errors
    print(traceback.format_exc(e))
    continue
except Exception as e:
    # everything else, possibly fatal
    print(traceback.format_exc(e))
    return

答案 1 :(得分:0)

通常我会尝试只处理在这种情况下实际上不可能的特定异常:谁知道将来cPickle.loads会抛出哪些异常。

如果不能在异常类型中更具体,我会尝试更加具体地在try ... except中包含的代码块。对于这个例子,这可能是这样的:

with open(self.session_filename, "rb") as f:
    uncompressed_data = zlib.decompress(f.read())

try:
    data = cPickle.loads(uncompressed_data)
except cPickle.UnpicklingError:
    raise
except Exception as e:
    # Unpickling failed
    raise cPickle.UnpicklingError(repr(e))