如何避免在Python中增加复杂性/缩进的嵌套尝试

时间:2011-10-07 12:10:19

标签: python

我有这样的代码:

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. 解析请求
  2. 用于生成处理请求的对象的工厂函数
  3. 我可以很容易地想象这会达到4级并且变得过于复杂而不适合我们的微不足道的推理。是否有一种Pythonic方法来压平压痕并使其“线性”?

4 个答案:

答案 0 :(得分:2)

Errors should not pass silently。如果你问我,在这种情况下打印消息而不是引发异常就算是“默默地”。

调用exit()更糟糕 - 无论何时调用您的函数,无论导入的库有多深,格式错误的请求都会终止该程序。

更多Pythonic替代打印消息然后忽略erorr或调用exit(),就是让此代码的调用者捕获异常并处理它。您不需要在此函数中进行任何异常处理。

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

答案 1 :(得分:1)

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

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'

StackOverflow上有一个很好的answer by Blair Conrad,它解释了为什么你可能想要使用else子句。

答案 2 :(得分:0)

在这种情况下,您在最高级别捕获异常后调用exit(),因此您可以这样做:

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

答案 3 :(得分:0)

在每次失败后保留函数/脚本(就像第一次失败一样) - 然后您不需要缩进以下代码,因为它在失败后无法运行。

根据此代码的位置,您希望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'