5

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


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

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

4

6 回答 6

11

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

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

其次,因为try块通常表明您正在执行某种异常处理,而您没有,您只是为了方便而使用它们。所以这个结构会让人们感到困惑。

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

于 2010-08-16T21:16:35.540 回答
11

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

这个更好:

if x:
    ret = update(1)
else:
    ret = update(2)
notifyUpdated()
return ret
于 2010-08-16T21:22:00.450 回答
3

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

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

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

于 2010-08-16T21:21:58.257 回答
3

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

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

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

于 2010-08-16T21:26:07.827 回答
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)
于 2010-08-16T22:45:31.907 回答
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

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

于 2010-08-16T21:15:17.847 回答