是否有一个更简洁的替代`except:pass`?

Ian*_*non 7 python coding-style exception-handling

我有一个函数,按优先顺序返回几个组的随机成员.它是这样的:

def get_random_foo_or_bar():
    "I'd rather have a foo than a bar."

    if there_are_foos():
        return get_random_foo()

    if there_are_bars():
        return get_random_bar()

    raise IndexError, "No foos, no bars"
Run Code Online (Sandbox Code Playgroud)

然而,首先要做的get_random_foo是验证是否有foos并且IndexError如果没有则提高,所以there_are_foos是多余的.此外,涉及数据库并使用单独的函数会产生并发问题.因此,我重写了这样的事情:

def get_random_foo_or_bar():
    "Still prefer foos."

    try:
        return get_random_foo()
    except IndexError:
        pass

    try:
        return get_random_bar()
    except IndexError:
        pass

    raise IndexError, "No foos, no bars"
Run Code Online (Sandbox Code Playgroud)

但我发现这个可读性要低得多,而且在我pass觉得错误之前我没有理由使用它.

是否有更整洁有效的模式,还是我应该学会接受pass

注意:我想避免任何嵌套,因为以后可能会添加其他类型.


编辑

谢谢所有说这pass很好的人 - 这让人放心!

还要感谢那些建议用返回值替换异常的人None.我可以看到这是一个有用的模式,但我认为在这种情况下它在语义上是错误的:已经要求函数执行一个不可能完成的任务,因此它们应该引发异常.我更喜欢遵循random模块的行为(例如random.choice([])).

Joh*_*ica 13

这正是我写它的方式.这很简单,也很有道理.我认为这些pass陈述没有问题.

如果您想减少重复次数并且预计会添加未来类型,则可以将其转换为循环.然后你可以改变pass一个功能相当的continue语句,如果你的眼睛更令人愉悦:

for getter in (get_random_foo, get_random_bar):
    try:
        return getter()
    except IndexError:
        continue  # Ignore the exception and try the next type.

raise IndexError, "No foos, no bars"
Run Code Online (Sandbox Code Playgroud)


小智 6

使用 try、 except、 pass 是可以接受的,但是有一种更简洁的方法可以使用contextlib.suppress()适用于 python 3.4+ 的方法来编写此代码。

from contextlib import suppress

def get_random_foo_or_bar():
    "Still prefer foos."

    with suppress(IndexError):
        return get_random_foo()

    with suppress(IndexError):
        return get_random_bar()

    raise IndexError("No foos, no bars")
Run Code Online (Sandbox Code Playgroud)