Python 与 try-except-finally 中的 return 值混淆

Python confusion with return value in try-except-finally

这是我的一段代码:

def main():
    num = 0
    try:
        raise Exception('This is the error message.')
    except Exception:
        num += 1
        return num
    finally:
        num += 1

a = main()
print(a)

returning 值是 1 而不是 2,这对我来说意义不大。

我认为它会 return 2 因为 finally 应该在 return 值之前执行。

谁能帮我理解一下?

finally 在 return 计算值之前执行,但是 return 值已经被计算。

return num 计算 num,得到 1,然后 finally 块开始。 finally 块递增 num,但是 return 值已经计算过,所以这无关紧要。最后,之前计算的 1 是 returned.

您 运行 了解标识符和值之间的区别。 num += 1 正在创建一个新的 int 对象并分配 num 标识符以指向它。它不会更改标识符已指向的 int 对象。 (对于小值,int 对象被缓存,但这是一个实现细节)

您可以在下面的代码中看到与确实改变对象的操作的区别:

def y():
    l = []
    try:
        raise Exception
    except Exception:
        print("except")
        l.append(1)
        return l
    finally:
        print("finally")
        l.append(2)

print(y())
# except
# finally
# [1, 2]

那是因为你在 except 块中 returning 使用 return 字将结束此函数中的代码执行。 为了避免它,你可以这样写:

def main():
 num = 0
 try:
    raise Exception('This is the error message.')
 except Exception:
    num += 1
 finally:
    num += 1
 return num

a = main()
print(a)

执行了finally(这在documentation中有明确定义),但是当你return一个不可变对象时,修改是看不见的,因为您的 returned 名称现在是不同范围的一部分。

对于可变对象(例如列表),这会像您期望的那样工作:

def main():
    lst = [0]
    try:
        raise Exception('This is the error message.')
    except Exception:
        lst[0] += 1
        return lst
    finally:
        lst[0] += 1
a = main()
print(a)

输出:[2]