python继续,除非条件不满足

时间:2012-09-11 17:12:58

标签: python try-catch

我经常发现自己想要做这样的事情,我有尝试这样的事情

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

有没有这样做?

4 个答案:

答案 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的代码不会在此结束。