代码之家  ›  专栏  ›  技术社区  ›  Ian Mackinnon

有没有比“except:pass”更整洁的选择?

  •  6
  • Ian Mackinnon  · 技术社区  · 14 年前

    我有一个函数,它按照优先顺序返回了几个组中的一个随机成员。就像这样:

    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"
    

    但是,首先 get_random_foo 是否确认存在FOO并提出 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"
    

    但是我发现这个不太可读,而且我从来没有理由使用它 pass 在感觉到错误之前。

    有没有更整洁有效的模式,或者我应该学会接受 通过 ?

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


    编辑

    谢谢所有说这个的人 通过 很好-这让人放心!

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

    7 回复  |  直到 14 年前
        1
  •  13
  •   John Kugelman Michael Hodel    14 年前

    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"
    
        2
  •  2
  •   Alex Martelli    14 年前

    pass

    try: return get_random_foo()
    except IndexError:
        try: return get_random_bar()
        except IndexError:
            raise IndexError "no foos, no bars"
    

    import this

        3
  •  2
  •   Peter Gibson    14 年前

    get_random_foo()

    def get_random_foo_wrapper():
        try:
            return get_random_foo()
        except IndexError:
            return None
    
    def get_random_foo_or_bar():
        "I'd rather have a foo than a bar."
    
        return get_random_foo_wrapper() or get_random_bar_wrapper() or None
    

    or

        4
  •  1
  •   Amber    14 年前

    try:
        return get_random_foo()
    except IndexError:
        try:
            return get_random_bar()
        except IndexError:
            raise IndexError, "No foos, no bars"
    

        5
  •  0
  •   kindall    14 年前

    def maketrap(*exceptions):
        def trap(func, *args, **kwargs):
            try:
                return func(*args, **kwargs)
            except exceptions:
                return None
        return trap
    
    def get_random_foo_or_bar():
        mytrap = maketrap(IndexError)
        return mytrap(get_random_foo) or mytrap(get_random_bar) or None
    
        6
  •  0
  •   Santa    14 年前

    def get_random_foo_or_bar():
        try:
            return get_random_foo()
        except IndexError:
            return get_random_bar()    # if failing at this point,
                                       # the whole function will raise IndexError
    
        7
  •  0
  •   Russell Borogove    14 年前

    def get_random_foo_or_bar():
        return get_random_foo() or get_random_bar()