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
仅在没有满足其他条件的情况下运行,但只有在满足其他条件时才会运行。
答案 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
注意事项当然是您的条件键必须是唯一且可清除的。您可以使用不同的数据结构来解决这个问题。