【问题标题】:How to write multiple try statements in one block in python?如何在python的一个块中编写多个try语句?
【发布时间】:2012-12-14 07:52:40
【问题描述】:

我想做:

try:
    do()
except:
    do2()
except:
    do3()
except:
    do4()

如果do()失败,执行do2(),如果do2()也失败,执行do3()等等。

最好的问候

【问题讨论】:

  • 我有一种感觉,描述您的具体用例将导致一个更优雅的解决方案的答案......

标签: python exception exception-handling


【解决方案1】:

如果您真的不关心异常,您可以循环使用案例直到成功:

for fn in (do, do2, do3, do4):
    try:
        fn()
        break
    except:
        continue

这至少避免了必须为每个案例缩进一次。如果不同的函数需要不同的参数,您可以使用 functools.partial 在循环之前为它们“准备”。

【讨论】:

  • pass 应该是continue 吧?按书面方式工作,但 continue 在语义上更清晰。
  • @Triptych 是的,这确实更好地表明了意图。编辑答案。
【解决方案2】:

我会为此编写一个快速包装函数first()

用法value = first([f1, f2, f3, ..., fn], default='All failed')

#!/usr/bin/env


def first(flist, default=None):

    """ Try each function in `flist` until one does not throw an exception, and
    return the return value of that function. If all functions throw exceptions,
    return `default` 

    Args: 
        flist - list of functions to try
        default - value to return if all functions fail

    Returns:
        return value of first function that does not throw exception, or
        `default` if all throw exceptions.

    TODO: Also accept a list of (f, (exceptions)) tuples, where f is the
    function as above and (exceptions) is a tuple of exceptions that f should
    expect. This allows you to still re-raise unexpected exceptions.
    """

    for f in flist:
        try:
            return f()
        except:
            continue
    else:
        return default

# Testing.

def f():
    raise TypeError

def g():
    raise IndexError

def h():
    return 1


# We skip two exception-throwing functions and return value of the last.
assert first([f, g, h]) == 1

assert first([f, g, f], default='monty') == 'monty'

【讨论】:

    【解决方案3】:

    这似乎是一件很奇怪的事情,但我可能会遍历函数并在没有引发异常时中断:

    for func in [do, do2, do3]:
        try:
            func()
        except Exception:
            pass
        else:
            break 
    

    【讨论】:

    • 创建,但这里还有什么用?这里似乎是多余的。
    • else 只会在没有异常时执行。如果有异常,for 将继续,而如果没有异常,break 将执行。 :) Python 中的许多语句都使用else,其目的是“如果一切顺利,那么就这样做”。请参阅try 声明的文档:docs.python.org/3/reference/compound_stmts.html#try
    【解决方案4】:

    这里是我找到的最简单的方法,只是在前面的except下嵌入try即可。

    try:
        do()
    except:
        try:
            do2()
        except:
            do3()
    

    【讨论】:

    • 我做了同样的事情,但不能让它更紧凑吗?
    【解决方案5】:

    您应该指定每次尝试捕获的异常的类型。

    try:
        do()
    except TypeError: #for example first one - TypeError
        do_2()
    except KeyError: #for example second one - KeyError
        do_3()
    

    等等。

    【讨论】:

    • 如果我不知道异常的类型?
    • @alwbic:如果你不知道异常的类型,你就不知道如何处理异常。
    • @alwbic 我真的很确定你一定知道你期望什么类型的异常。
    • 我不同意你的看法。我知道我的陈述会失败,但我不知道他们会以什么顺序失败。但我知道如果失败了该怎么办。
    • @alwbic:“如果某事失败就做某事”只是一种不好的做法,你现在不知道为什么会失败。
    【解决方案6】:
    import sys
    
    try:
        f = open('myfile.txt')
        s = f.readline()
        i = int(s.strip())
    except OSError as err:
        print("OS error: {0}".format(err))
    except ValueError:
        print("Could not convert data to an integer.")
    except:
        print("Unexpected error:", sys.exc_info()[0])
        raise
    

    【讨论】:

    • 这根本不能回答问题!
    • 这个答案我笑得很厉害,谢谢你让我开心
    猜你喜欢
    • 1970-01-01
    • 2010-10-29
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-30
    相关资源
    最近更新 更多