我知道' tryelse'这不是一个真实的东西,但我的问题是关于写出这个逻辑的最好方法。给出以下示例,foo和bar是可能会破坏的函数。
我希望aa
成为foo()
,但如果中断,我希望它成为bar()
,但如果那个中断,则将aa
设置为0作为默认值。
try:
aa = foo()
elsetry:
aa = bar()
except e:
aa = 0
重述我的问题,在python中写出这个逻辑的最佳方式是什么?
答案 0 :(得分:4)
如果你有这些的长链或动态备选方案列表,你可能想要使用for
循环:
for func in funcs:
try:
aa = func()
break
except:
pass
else:
aa = 0
请注意,无论哪种方式,您都可能 想要裸except
。通常你只是期望一些特定类型的错误(例如,ValueError
或LookupError
),而其他任何东西都不应该意味着“默默地尝试下一个”但是“向程序员展示出意外的事情发生了错误”。但是你知道如何解决这个问题。
如果您需要重复使用它,当然可以将其包装在一个函数中:
def try_funcs(*funcs, defval=0, ok_exceptions=Exception):
for func in funcs:
try:
return func()
except ok_exceptions: # ok_exceptions can also be a tuple of exception classes.
pass
return defval
当然,正如评论中所提到的,这确实要求您想要尝试的所有内容都是无参数的函数。如果您想尝试spam(42)
,然后eggs(beans)
,如果失败,该怎么办?或者甚至不是函数调用的东西,还有其他一些表达式,比如foo[bar]
?
这与遍布Python的一般情况相同:您使用partial
绑定第一种情况的参数,或者为第二种情况编写包含lambda
的包装函数:
result = try_funcs(partial(spam, 42), partial(eggs, beans), lambda: foo[bar])
但是,如果您只有两个或三个静态替代品尝试,Simon Visser's simple nested answer会更清晰。
如果你问为什么这种语言没有你的tryelse
......好吧,我知道它出现在python-ideas / -dev列表和其他地方几次,并进行了讨论,因此您可能希望搜索更详细/权威的答案。但是我认为它归结为:虽然理论上可以用tryelse
来提出看起来更清晰的案例,但是任何人给出的每个例子都是好的,或者显然应该被重构,所以有没有令人信服的论据来改变语法,保留一个新的关键词等等。
答案 1 :(得分:3)
嵌套方法仍然是最好的:
try:
aa = foo()
except Exception:
try:
aa = bar()
except Exception:
aa = 0
尽管尝试用较少的嵌套来做,但上面表达了你想做的事情并且对读者来说很清楚。如果你试图嵌套更多,那么写作就变得很尴尬了,是时候重新思考你的方法了。但是嵌套两个尝试/排除很好。
你也可以写:
try:
aa = foo()
except Exception:
aa = None
if aa is None:
try:
aa = bar()
except Exception:
aa = 0
但不知何故看起来不对(至少对我来说)。如果foo()
可以将None
作为aa
的有效值返回,也会出现错误。
答案 2 :(得分:1)
我认为这是最好的方法:
try:
aa = foo()
except:
try:
aa = bar()
except:
aa = 0
这就是你在JavaScript中没有elif语句时所做的事情:
if if_condition:
code
else:
if elif_condition:
code
else:
code