'尝试'内部'加注',何时以及如何使用'加注'?

时间:2018-01-25 03:49:54

标签: python

所以这是代码:

def fancy_divide(list_of_numbers, index):
    try:
        try:
            raise Exception("0")
        finally:
            denom = list_of_numbers[index]
            for i in range(len(list_of_numbers)):
            l    ist_of_numbers[i] /= denom
    except Exception as ex:
        print(ex)

如果我打电话:

fancy_divide([0, 2, 4], 0)

为什么不打印'0'?

如果我编辑这样的代码:

def fancy_divide(list_of_numbers, index):
    try:
        try:
            raise Exception("0")
        finally:
            denom = list_of_numbers[index]
            for i in range(len(list_of_numbers)):
                list_of_numbers[i] /= denom
    except Exception as ex:
        raise Exception("0")
        print(ex)

然后调用相同的东西,打印出来:

Traceback (most recent call last):

  File "<ipython-input-16-c1b0ac98281c>", line 1, in <module>
    fancy_divide([0, 2, 4], 0)

  File "/Users/dsn/.spyder-py3/temp.py", line 10, in fancy_divide
    raise Exception("0")

Exception: 0

为什么?什么是正确的方式/何时应该使用加注?

2 个答案:

答案 0 :(得分:1)

你的finally块本身就会引发一个异常,一个被零除错误(因为你的分母是0)。如果finally块作为异常冒泡而执行,并引发其自身的异常,则它可以:

  1. 在Python 2上,替换现有的异常
  2. 在Python 3上,它将现有异常包装在新异常中(创建一系列异常,其中最外层的异常是被检查的异常,但是上下文存在内部异常)
  3. 您的其他代码会打印回溯,因为您根本没有捕到您提出的第二个异常(并且它会绕过您的print)。

    我建议reading the exception tutorial了解更多;你的示例代码是如此做作/毫无意义,你无法说出你真正有什么误解,以及只是为了说明支持你的问题的特定行为。

答案 1 :(得分:1)

def fancy_divide(list_of_numbers, index):
    try:
        try:
            raise Exception("0")  # 1
        finally:
            denom = list_of_numbers[index]
            for i in range(len(list_of_numbers)):
            list_of_numbers[i] /= denom
    except Exception as ex:
        print(ex)  # 2

注意数字

1.这件事首先触发第二except之外的try区块而忽略其他区块。

2.由于try块中存在异常,这将被触发。

except块内使用raise来避免复杂的事情。

我会将您的代码重写为:

def fancy_divide(list_of_numbers, index):
    try:
        # Your fancy divide logic here
    except Exception as ex:
        raise Exception('Something went wrong: {exception}'.format(exception=ex))
    finally:
        # Don't need to