在python中编写“try elsetry”的最佳方法?

时间:2014-12-05 22:25:10

标签: python try-catch

我知道' tryelse'这不是一个真实的东西,但我的问题是关于写出这个逻辑的最好方法。给出以下示例,foo和bar是可能会破坏的函数。

我希望aa成为foo(),但如果中断,我希望它成为bar(),但如果那个中断,则将aa设置为0作为默认值。

try:
    aa = foo()
elsetry:
    aa = bar()
except e:
    aa = 0

重述我的问题,在python中写出这个逻辑的最佳方式是什么?

3 个答案:

答案 0 :(得分:4)

如果你有这些的长链或动态备选方案列表,你可能想要使用for循环:

for func in funcs:
    try:
        aa = func()
        break
    except:
        pass
else:
    aa = 0

请注意,无论哪种方式,您都可能 想要裸except。通常你只是期望一些特定类型的错误(例如,ValueErrorLookupError),而其他任何东西都不应该意味着“默默地尝试下一个”但是“向程序员展示出意外的事情发生了错误”。但是你知道如何解决这个问题。


如果您需要重复使用它,当然可以将其包装在一个函数中:

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