Try-Except-Else-finally返回in else替代?

时间:2017-02-11 15:43:39

标签: python python-2.7 exception

我正在开发一个可以raise多个Exceptions的函数。我想在其except块中处理这些Exceptions,然后使用自定义消息和回溯返回结果。问题是finally得到保证,因此我无法在else块内返回任何内容。

如果引发了一些Exception,则此代码有效但如果没有Exception则不起作用。在这种情况下,我只想返回{'success':True}

所以从这段代码:

def foo():
    try:
        #some code
        return {'success':True}
    except FirstException:
        tb = traceback.format_exc()
        msg = 'There was FirstExc'
        return {'success':False,
                'tb':tb,
                'msg':msg}
    except SecondException:
        tb = traceback.format_exc()
        msg = 'There was SecondExc'
        return {'success':False,
                'tb':tb,
                'msg':msg}
    ...

我不想重复returns。我试过了:

def foo():
    try:
        pass
    except FirstException:
        tb = traceback.format_exc()
        msg = 'There was FirstExc'
    except SecondException:
        tb = traceback.format_exc()
        msg = 'There was SecondExc'
    else:
        return {'success':True}
    finally:
        return {'success':False,
                'tb':tb,
                'msg':msg}

你知道怎么做吗?我知道我可以将return {'success':True}放入try块,删除finallyelse块,并将return {'success':False,'tb':tb,'msg':msg}添加到每个except块中,但有很多except阻塞,因此代码将重复多次。

还有其他选择吗?

2 个答案:

答案 0 :(得分:2)

不要使用finally块。您希望仅针对例外情况返回False,否则返回True;以finally返回始终适用于这两种情况。

您可以从except套房返回,也可以组合套房。

两者的回归导致更多的重复:

def foo():
    try:
        pass
    except FirstException:
        tb = traceback.format_exc()
        msg = 'There was FirstExc'
        return {'success':False,
                'tb':tb,
                'msg':msg}
    except SecondException:
        tb = traceback.format_exc()
        msg = 'There was SecondExc'
        return {'success':False,
                'tb':tb,
                'msg':msg}
    else:
        return {'success':True}

您可以将except套件合并为一个:

def foo():
    try:
        pass
    except (FirstException, SecondException) as e:
        tb = traceback.format_exc()
        exception_type = 'FirstExc' if isinstance(e, FirstException) else 'SecondExc'
        msg = 'There was {}'.format(exception_type)
        return {'success':False,
                'tb':tb,
                'msg':msg}
    else:
        return {'success':True}

另一种选择是首先构建返回值 ,然后根据需要添加信息:

def foo():
    result = {'success': True}
    try:
        pass
    except FirstException:
        tb = traceback.format_exc()
        msg = 'There was FirstExc'
        result = {'success': False, 'tb': tb, 'msg': msg}
    except SecondException:
        tb = traceback.format_exc()
        msg = 'There was SecondExc'
        result = {'success': False, 'tb': tb, 'msg': msg}
    finally:
        return result

然而,这与return - 来自除套房之外的选项完全不同。

答案 1 :(得分:1)

def foo():
    success = False
    try:
        pass
    except FirstException:
        tb = traceback.format_exc()
        msg = 'There was FirstExc'
    except SecondException:
        tb = traceback.format_exc()
        msg = 'There was SecondExc'
    else:
        success = True
    finally:
        return {'success':success,
                'tb':tb,
                'msg':msg} if not success else {'success':success}

替代:

def foo():
    result = {"success": False}
    try:
        pass
    except FirstException:
        result['tb'] = traceback.format_exc()
        result['msg'] = 'There was FirstExc'
    except SecondException:
        result['tb'] = traceback.format_exc()
        result['msg'] = 'There was SecondExc'
    else:
        result['success'] = True
    finally:
        return result

上述略有变化:

def foo():
    result = {"success": False}
    try:
        pass
    except FirstException:
        result.update({'tb': traceback.format_exc(), 'msg': 'There was FirstExc'})
    except SecondException:
        result.update({'tb': traceback.format_exc(), 'msg': 'There was SecondExc'})
    else:
        result['success'] = True
    finally:
        return result