python try/finally 用于流量控制

发布于 2024-09-14 18:28:13 字数 252 浏览 8 评论 0原文

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


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

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

I'm sure this concept has come up before but I can't find a good, simple answer. Is using try/finally a bad way to handle functions with multiple returns? For example I have


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

This just seems nicer than storing update() commands in a temporary variable and returning that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

酒中人 2024-09-21 18:28:13

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

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

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

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

I wouldn't recommend it. First because notifyUpdated() will be called even if the code in either branch throws an exception. You would need something like this to really get the intended behavior:

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

Secondly, because try blocks generally indicate you're doing some kind of exception handling, and you aren't, you're just using them for convenience. So this construct will confuse people.

For example, I don't think either of the first two people (at least one of which deleted their answer) to answer your question realized what you were really trying to do. Confusing code is bad, no matter how convenient and clever it seems.

无远思近则忧 2024-09-21 18:28:13

我不会将 try/finally 用于不涉及异常的流程。它本身就太棘手了。

这是更好的:

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

I would not use try/finally for flow that doesn't involve exceptions. It's too tricky for its own good.

This is better:

if x:
    ret = update(1)
else:
    ret = update(2)
notifyUpdated()
return ret
心的憧憬 2024-09-21 18:28:13

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

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

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

I think you mean you want to use try/finally as an alternative to this:

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

I guess this is a matter of style. For me I like to reserve try for handling exceptional conditional. I won't use it as a flow control statement.

桃酥萝莉 2024-09-21 18:28:13

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

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

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

I think this is asking for trouble. What happens later, when you change your code to the following?

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

At best, it's a stumbling point for most readers of your code (probably even you in six months), because it's using try/finally for a purpose that differs from the normal use patterns. And the typing it saves is minimal, anyway.

对不⑦ 2024-09-21 18:28:13

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

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)

I think a decorator is a better idea here

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)
帅气尐潴 2024-09-21 18:28:13

来自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

所以您可以创建一个类似的函数并使用它

from 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

so you can create a similar function and use it

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文