如何避免在Python中增加复杂性/缩进的嵌套try-s



我有这样的代码:

try:
    request=parse_request
except:
    print "cannot parse your malformed request"
    exit()
else:
    try:
        fh=a_factory_function()
    except:
        print "cannot create object"
    else:
        if request['operation']=='search':
            pass
        elif request['operation']=='more_like_this':
            pass
        elif request['operation']=='list_files':
            pass
        elif request['operation']=='update':
            pass
        else:
            print 'unsupported operation'

当前格式有两层缩进

    解析请求
  1. 工厂函数,生成一个对象来处理请求

我可以很容易地想象这将达到4个级别,并且对于我们微不足道的推理来说变得过于复杂。是否有一种python的方法来平缩进并使其"线性"?

错误不应该静默传递。如果你问我,在这种情况下,打印消息而不是引发异常算作"静默"。

调用exit()更糟糕——任何时候调用函数,无论在导入的库中有多深,格式错误的请求都将终止程序。

比起打印消息然后忽略错误或调用exit(),更python的替代方法是让该代码的调用者捕获异常并处理它。在这个函数中不需要任何异常处理。

如果您需要区分解析错误和对象创建错误,则引发自定义ParseErrorObjectCreationError,并让调用者处理它们。正如其他答案所建议的那样,如果一个块以raise(或exit()return)结束,则不需要在其后面缩进else块。

除非我误解了您的代码,否则您正在使用try语句的else子句进行正常处理。实际上,您正在模拟异常的返回代码错误处理。为什么不这样做呢?

try:
    request=parse_request
    fh=a_factory_function()
except MalformedRequestError:
    print "cannot parse your malformed request"
    exit()
except CreateObjectError:
    print "cannot create object"
    exit()
if request['operation']=='search':
    pass
elif request['operation']=='more_like_this':
    pass
elif request['operation']=='list_files':
    pass
elif request['operation']=='update':
    pass
else:
    print 'unsupported operation'
Blair Conrad在StackOverflow上给出了一个很好的答案,解释了为什么你可能想要使用else子句。

在本例中,您在顶层捕获异常后调用exit(),因此您可以这样做:

try:
    request=parse_request
except:
    print "cannot parse your malformed request"
    exit()
try:
    # and so on

在每次失败后保留函数/脚本(就像您对第一次失败所做的那样)——那么您不需要缩进下面的代码,因为它不可能在失败后运行。

根据这段代码的位置,您想要raise您自己的自定义错误,或return而不是退出。

try:
    request=parse_request
except:
    print "cannot parse your malformed request"
    exit()
try:
    fh=a_factory_function()
except:
    print "cannot create object"
    exit()
if request['operation']=='search':
    pass
elif request['operation']=='more_like_this':
    pass
elif request['operation']=='list_files':
    pass
elif request['operation']=='update':
    pass
else:
    print 'unsupported operation'

最新更新