'Finally'等效于Python中的If / Elif语句

时间:2014-02-06 20:06:39

标签: python finally

Python的finally语句是否等效if/else,类似于try/except/finally语句?可以让我们简化这个的东西:

 if condition1:
      do stuff
      clean up
 elif condition2:
      do stuff
      clean up
 elif condition3:
      do stuff
      clean up
 ...
 ...

到此:

 if condition1:
      do stuff
 elif condition2:
      do stuff
 elif condition3:
      do stuff
 ...
 ...
 finally:
      clean up

只有在满足条件并且“执行东西”运行后才会调用finally?相反,如果没有满足条件,则不会运行finally代码。

我讨厌亵渎神灵,但我能描述的最好的方法就是在每个“do stuff”块的末尾都有一个GOTO语句,导致finally

基本上,它与else语句相反。虽然else仅在没有满足其他条件的情况下运行,但只有在满足其他条件时才会运行。

8 个答案:

答案 0 :(得分:10)

这可以完全不像这样完成:

def function(x,y,z):
    if condition1:
        blah
    elif condition2:
        blah2
    else:
        return False

    #finally!
    clean up stuff.

在某些方面,并不方便,因为您必须使用单独的功能。但是,好的做法是不要做太长的功能。将您的逻辑分成易读的小(通常最多1页长)函数,可以更轻松地测试,记录和理解执行流程。

需要注意的一点是,finally子句在发生异常时不会运行。要做到这一点,您还需要在其中添加try:内容。

答案 1 :(得分:3)

你的逻辑类似于:

cleanup = True
if condition1:
    do stuff
elif condition2:
    do stuff
elif condition3:
    do stuff
....
else:
    cleanup = False

if cleanup:
    do the cleanup

丑陋,但这就是你问的问题

答案 2 :(得分:2)

mhlester的答案有重复的代码,改进的版本可能如下:

class NoCleanUp(Exception):
    pass

try:
    if condition1:
        do stuff
    elif condition2:
        do stuff
    else:
        raise NoCleanUp
except NoCleanUp:
    pass
else:
    cleanup

答案 3 :(得分:1)

另一个建议,如果条件是预先计算的,可能适合你。

if condition1:
    do stuff
elif condition2:
    do stuff
...
if any([condition1, condition2, ...]):
    clean_up

如果您将条件作为if语句的一部分进行评估,那将会很痛苦,因为在这种情况下,您必须第二次对any函数进行评估...除非Python比我意识到了。

答案 4 :(得分:1)

派对有点晚了,但最近看到问题一直很活跃。

通常我会像这样制作一个上下文管理器

class CleanUp(object):

    class Cancel(Exception):
        pass

    def __init__(self, f_cleanup):
        self.f_cleanup = f_cleanup

    def __enter__(self):
        return self

    def __exit__(self, exception_type, exception_value, traceback):

        cancelled = exception_type and issubclass(exception_type, self.__class__.Cancel)

        if not cancelled:
            self.f_cleanup()

        return not exception_type or cancelled

    def cancel(self):
        raise self.__class__.Cancel

然后你可以像这样使用它

def cleanup():
    print "Doing housekeeping"


with CleanUp(cleanup) as manager:
    if condition1:
        do stuff
    elif condition2:
        do stuff
    else:
        manager.cancel()

答案 5 :(得分:1)

您可以使用try

IF(A1="PROMOTERS",RANDBETWEEN(9,10),IF(A1="PASSIVE",RANDBETWEEN(7,8),IF(A1="DETRACTORS",RANDBETWEEN(0,6),"Error")))

引发异常,但清理完成

答案 6 :(得分:0)

这很可怕吗?

for _ in range(1):
    if condition1:
        do stuff
        break
    elif condition2:
        do stuff
        break
else:
    finally stuff

这个怎么样?

class NoFinally(Exception):
    pass

try:
    if condition1:
        do stuff
        raise NoFinally
    elif condition2:
        do stuff
        raise NoFinally
except NoFinally:
    pass
else:
    finally

老实说,我讨厌这两个

答案 7 :(得分:0)

像这样:

from .actions import stuff1, stuff2

actions={condition1: stuff1, condition2: stuff2}
for condition in actions:
    if condition:
        actions[condition]()
        cleanup()
        break

注意事项当然是您的条件键必须是唯一且可清除的。您可以使用不同的数据结构来解决这个问题。