我经常发现自己想要做这样的事情,我有尝试这样的事情
item= get_item()
try:
do_work(item)
except SomeError as err:
if err.code == 123:
do_something(item)
else:
# Actually I don't want to do something with this error code... I want to handle in 'except'
except:
put_back(item)
raise
有没有办法从其他地方加入下面的except
区块? (一个continue
会很好)我最终做了类似下面的事情,而不是那么干净
item= get_item()
try:
try:
do_work(item)
except SomeError as err:
if err.code == 123:
do_something(item)
else:
raise
except:
put_back(item)
raise
有没有这样做?
答案 0 :(得分:8)
如果您使用的是最新的python版本(2.5及更高版本),则应切换为使用context manager代替:
class WorkItemContextManager(object):
def __enter__(self):
self.item = get_item()
return self.item
def __exit__(self, exc_type, exc_value, tb):
if exc_type is not None:
if exc_type is SomeError and exc_value.code == 123:
do_something(self.item)
return True # Exception handled
put_back(self.item)
然后:
with WorkItemContextManager() as item:
do_work(item)
如果处理了异常,__exit__
方法可以返回True;返回None将重新引发with
块中引发的任何异常。
如果没有,您正在寻找finally
块:
item = get_item()
try:
do_work(item)
item = None
except SomeError as err:
if err.code == 123:
do_something(item)
item = None
finally:
if item is not None:
put_back(item)
finally
套件保证在try:
套件完成,或发生异常时执行。通过将item
设置为None
,您基本上可以告诉finally
套件一切正常,无需将其恢复。
finally
处理程序从您的毯子except
处理程序接管。如果do_work
中存在例外,item
将不会设置为无。如果SomeError
处理程序未捕获异常,或err.code
不 123,item
也将不会设置为None,因此put_back(item)
1}}方法被执行。
答案 1 :(得分:2)
我的建议是创建一个函数(或一系列函数)来包装抛出你想要控制的错误的方法。有点像...
def wrapper(arg):
try:
do_work(arg)
except SomeError as e:
if e.code == 123:
do_something(item)
# Other possible cleanup code
else:
raise
...然后,当你想打电话给它时......
try:
wrapper(arg)
except SomeError as e:
put_back(arg)
答案 2 :(得分:1)
最好记住try-except流程的用途,并且它们的一个优点是它们不需要状态变量和状态检查,如
if not foo:
# do something
此外,Exception类应表示特定类型的错误。如果您需要对except块中的错误类型做出进一步的决定,那么这是一个很好的信号,表明该类不足以表示程序状态。你最好的选择是继承SomeError并只捕获第一个子类,除了。然后SomeError的其他实例将落到第二个除了块之外。
答案 3 :(得分:1)
上下文管理器非常出色,但对于一些不会在其他任何地方重用逻辑的简单情况,它们可能会有点沉重。
您可以在单个except
块中测试异常,而不是尝试拥有多个except
块:
item= get_item()
try:
do_work(item)
except Exception as err:
if isinstance(err, SomeError) and err.code == 123:
do_something(item)
else:
put_back(item)
raise
请注意,这几乎就是上下文管理器的__exit__
方法最终看起来的样子。
请注意,真正属于finally
的代码不会在此结束。