[python尝试/最终进行流控制

问题描述 投票:5回答:6

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


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

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

python control-flow try-catch-finally
6个回答
11
投票

我不推荐。首先,因为即使任一分支中的代码引发异常,也会调用notifyUpdated()。您需要这样的东西才能真正获得预期的行为:

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

[其次,因为try块通常表明您正在执行某种异常处理,但实际上并非如此,您只是为了方便而使用它们。因此,这种构造会使人们感到困惑。

例如,我不认为回答您问题的前两个人中的任何一个(至少其中一个删除了他们的答案)都没有意识到您确实在尝试做什么。无论看起来多么方便和聪明,混乱的代码都是不好的。


11
投票

我不会将try / finally用于不涉及异常的流程。就其自身而言,这太棘手了。

这更好:

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

3
投票

我认为您是想使用try / finally作为替代方案:

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

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


3
投票

我认为这是自找麻烦。以后,当您将代码更改为以下代码时,会发生什么?

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

充其量,这是大多数代码阅读者的绊脚石(可能甚至六个月内也是如此),因为它使用try/finally的目的与正常使用模式不同。无论如何,它节省的打字量是最少的。


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)

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

因此您可以创建类似的功能并使用它

© www.soinside.com 2019 - 2024. All rights reserved.