python try / finally用于流控制

时间:2010-08-16 21:08:18

标签: python try-catch-finally flow-control

我确信这个概念已经出现过,但我找不到一个好的,简单的答案。使用try / finally是一种处理具有多个返回的函数的坏方法吗?例如,我有


try:
    if x:
        return update(1)
    else:
        return update(2)
finally:
    notifyUpdated()

这比将update()命令存储在临时变量中并返回它更好。

6 个答案:

答案 0 :(得分:11)

我不推荐它。首先是因为即使任一分支中的代码抛出异常,也会调用notifyUpdated()。你需要这样的东西来真正得到预期的行为:

try:
    if x:
        return update(1)
    else:
        return update(2)
except:
    raise
else:
    notifyUpdated()

其次,因为try块通常表示您正在进行某种异常处理,而您不是,所以您只是为了方便而使用它们。所以这个结构会让人迷惑。

例如,我不认为前两个人中的任何一个(至少有一个人删除了他们的答案)回答你的问题,意识到你真正想要做的事情。令人困惑的代码很糟糕,无论它看起来多么方便和聪明。

答案 1 :(得分:11)

我不会将try / finally用于不涉及异常的流。这对自己的利益来说太棘手了。

这样更好:

if x:
    ret = update(1)
else:
    ret = update(2)
notifyUpdated()
return ret

答案 2 :(得分:3)

我认为你的意思是你想用try / finally作为替代方法:

if x:
    result = update(1)
else:
    result = update(2)
notifyUpdated()
return result

我想这是一个风格问题。对我来说,我喜欢保留try来处理特殊条件。我不会将它用作流程控制语句。

答案 3 :(得分:3)

我认为这是在寻找麻烦。当您将代码更改为以下内容后会发生什么?

try:
    if x:
        return update(1)
    elif y:
        return update(2)
    else:
        return noUpdateHere()
finally:
    notifyUpdated() # even if noUpdateHere()!

充其量,对于大多数读者来说,这是一个绊脚石(可能在六个月内甚至是你),因为它使用try/finally的目的与正常的使用模式不同。无论如何,它保存的打字很少。

答案 4 :(得分:3)

我认为装饰师在这里是个更好的主意

def notifyupdateddecorator(f):
    def inner(*args, **kw):
        retval = f(*args, **kw)
        notifyUpdated()
        return retval
    return inner

@notifyupdateddecorator
def f(x):
    if x:
        return update(1)
    else:
        return update(2)

@notifyupdateddecorator
def g(x):
    return update(1 if x else 2)

答案 5 :(得分:0)

来自http://docs.python.org/library/contextlib.html


from contextlib import closing
import urllib

with closing(urllib.urlopen('http://www.python.org')) as page:
    for line in page:
        print line

所以你可以创建一个类似的功能并使用它

相关问题