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

2024-10-01 00:34:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道“tryelse”不是真的,但我的问题是如何用最好的方式写出这个逻辑。在下面的示例中,foo和bar是可能中断的函数。你知道吗

我希望aafoo(),但是如果它中断了,我希望它变成bar(),但是如果它也中断了,那么将aa设置为0作为默认值。你知道吗

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

重申我的问题,用python编写这个逻辑的最佳方法是什么?你知道吗


Tags: 方法函数示例foo方式bar逻辑aa
3条回答

如果您有一个长链或一个动态备选方案列表,您可能希望使用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可以得到看起来更干净的例子,但任何人给出的每个例子要么都很好,要么显然应该被重构,因此没有令人信服的理由来更改语法、保留新关键字等等

我认为这是最好的方法:

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

这是当您没有像JavaScript中那样的elif语句时所做的:

if if_condition:
   code
else:
   if elif_condition:
       code
   else:
        code

嵌套方法仍然是最好的:

try:
    aa = foo()
except Exception:
    try:
        aa = bar()
    except Exception:
        aa = 0

尽管尝试用较少的嵌套来实现,但上面的内容表达了您希望做的事情,读者也很清楚。如果你试图嵌套更多的东西,写起来会很尴尬,是时候重新考虑你的方法了。但是嵌套两个try/例外是好的。你知道吗

你也可以写:

try:
    aa = foo()
except Exception:
    aa = None

if aa is None:
    try:
        aa = bar()
    except Exception:
        aa = 0

但不知怎么的,这看起来不太对(至少对我来说是这样)。如果foo()可以将None作为aa的有效值返回,则也不正确。你知道吗

相关问题 更多 >