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

用python编写“try-elsery”的最佳方法?,python,try-catch,Python,Try Catch,我知道“tryelse”不是真的,但我的问题是关于写出这种逻辑的最佳方式。给出以下示例,foo和bar是可能会中断的函数 我希望aa是foo,但如果它断开,我希望它变成bar,但如果它也断开,那么将aa设置为0作为默认值 try: aa = foo() elsetry: aa = bar() except e: aa = 0 重申我的问题,用python编写这种逻辑的最佳实际方式是什么?我认为这是最好的方式: try: aa = foo() except:

我知道“tryelse”不是真的,但我的问题是关于写出这种逻辑的最佳方式。给出以下示例,foo和bar是可能会中断的函数

我希望aa是foo,但如果它断开,我希望它变成bar,但如果它也断开,那么将aa设置为0作为默认值

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

重申我的问题,用python编写这种逻辑的最佳实际方式是什么?

我认为这是最好的方式:

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:
    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/except是可以的

你也可以写:

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

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

但至少在我看来,这是不对的。如果foo可以将None作为aa的有效值返回,那么它也不正确。

嵌套方法仍然是最好的:

try:
    aa = foo()
except Exception:
    try:
        aa = bar()
    except Exception:
        aa = 0
尽管试图用较少的嵌套来完成,但上面的内容表达了您希望做的事情,读者对此很清楚。如果你想做更多的嵌套,写起来会很尴尬,是时候重新考虑你的方法了。但是嵌套两个try/except是可以的

你也可以写:

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

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

但至少在我看来,这是不对的。如果foo可以将None作为aa的有效值返回,那么这也是不正确的。

如果您有一个长链或一个动态替代列表,您可能希望使用for循环:

请注意,无论哪种方式,除了这里,您可能并不真正想要裸体。通常情况下,您只希望出现某些特定类别的错误,例如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
当然,正如在评论中提到的,这确实要求您想要尝试的所有东西都是一个没有参数的函数。如果你想试试spam42,如果失败了怎么办?或者甚至不是函数调用而是其他表达式的东西,比如foo[bar]

这与Python中出现的一般情况相同:第一种情况下使用partial绑定参数,第二种情况下使用lambda编写包装函数:

result = try_funcs(partial(spam, 42), partial(eggs, beans), lambda: foo[bar])
然而,如果你只是有一个静态的两个或三个备选方案来尝试,就更清楚了


如果你问为什么这种语言没有你的Trylese…我知道它已经出现在python的ideas/-dev列表和其他地方好几次了,并且已经讨论过了,所以你可能想搜索更详细/权威的答案。但我认为这可以归结为:虽然理论上可以用tryelse找到看起来更干净的例子,但任何人给出的每个例子要么都很好,要么显然应该重构,因此没有令人信服的理由改变语法,保留一个新的关键字,等等。

如果您有一个长链,或者有一个动态的备选方案列表,您可能希望使用for循环:

请注意,无论哪种方式,除了这里,您可能并不真正想要裸体。通常情况下,您只希望出现某些特定类别的错误,例如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
当然,正如在评论中提到的,这确实要求您想要尝试的所有东西都是一个没有参数的函数。如果你想试试spam42,如果失败了怎么办?或者甚至不是函数调用而是其他表达式的东西,比如foo[bar]

这与Python中出现的一般情况相同:第一种情况下使用partial绑定参数,第二种情况下使用lambda编写包装函数:

result = try_funcs(partial(spam, 42), partial(eggs, beans), lambda: foo[bar])
然而,如果你只是有一个静态的两个或三个备选方案来尝试,就更清楚了


如果你问为什么这种语言没有你的Trylese…我知道它已经出现在python的ideas/-dev列表和其他地方好几次了,并且已经讨论过了,所以你可能想搜索更详细/权威的答案。但我认为可以归结为这样一点:虽然理论上可以用tryelse找到看起来更干净的案例,但任何人给出的每个示例都可以保持原样,或者显然应该进行重构,因此没有令人信服的理由来更改语法、保留新关键字等。

第二种解决方案很尴尬。它不会减少压痕,也会使压痕更小
只有当foo失败时,您才想尝试bar+1对于第一个解决方案a.k.a正确的方法:我不打算像您这里这样有两个以上的中断函数,但出于好奇,如果我有五个或十个不同的中断函数,我希望这些函数与之一起使用,那最好是什么?@StevenRogers:您可以将所有函数添加到一个列表中,迭代列表并使用try/except调用每个函数。当第一个函数成功地给你一个值时,你就会跳出循环。第二个解决方案很尴尬。它并没有减少缩进,也不太清楚只有在foo失败的情况下才想尝试bar+1对于第一个解决方案a.k.a正确的方法:我不打算像您这里这样有两个以上的中断函数,但出于好奇,如果我有五个或十个不同的中断函数,我希望这些函数与之一起使用,那最好是什么?@StevenRogers:您可以将所有函数添加到一个列表中,迭代列表并使用try/except调用每个函数。一旦第一个函数成功地给你一个值,你就会跳出循环。请不要提倡使用bare Exception。捕获异常或更具体的东西。@roippi:他不是在提倡,他只是从问题中复制了它,就像这里的所有其他答案一样……请不要提倡使用裸除。抓住例外或更具体的东西。“罗比:他不是在鼓吹它,他只是从问题中复制它,就像这里的每一个答案一样……”米格森:“我只是在添加相同的东西,但是有一个不同的名字和更多的解释。”我保留了你的名字,还使用了Exception而不是Exception,,正如我将要说的那样…因为它更可读。谢谢。好主意!然而,当函数采用不同的形式时,使用起来就困难多了arguments@PiotrDabkowski:不难;当它实际上只是一个函数调用时,您只需要使用partial;当它是一个任意表达式时,您只需要编写lambda函数,这与任何需要传递空值可调用函数的情况完全相同,这种情况在Python中都会发生,例如。,Mgels:我只是在添加相同的东西,但是有一个不同的名字和更多的解释。我保留了你的名字,还使用了Exception而不是Exception,,正如我将要说的那样…因为它更可读。谢谢。好主意!然而,当函数采用不同的形式时,使用起来就困难多了arguments@PiotrDabkowski:不难;当它实际上只是一个函数调用时,您只需要使用partial;当它是一个任意表达式时,您只需要编写lambda函数,这与任何需要传递空值可调用函数的情况完全相同,这种情况在Python中都会发生,例如Tkinter或Twisted回调。