Python 装饰器 Try/Except 不引发错误

Python Decorator With Try/Except Not Raising Error

我正在试验 Python 装饰器以了解它发生了什么,我遇到了一个令人头疼的问题。

我的代码是这样的(python 2.7.6):

import traceback
def dec(func):
    def wrapped(*args, **kwargs):
        try:
            if flag:
                print 'flagged'
            else:
                print 'unflagged'
        except NameError as e:
            print 'error?'
            raise
        finally:
            return func(*args, **kwargs)
    return wrapped

@dec
def foo(x):
    print x

foo(3)

当运行时,输出为:

error?
3

我预计调用 foo(3) 会引发:

NameError: global name 'flag' is not defined

为什么 "raise" 没有加注?显然,错误已被捕获 - Except 块中的打印已执行...

finally 中的 return 覆盖并取消任何可能触发 finally 块的异常或函数 return。这记录在 Python Language Reference:

If finally is present, it specifies a ‘cleanup’ handler. The try clause is executed, including any except and else clauses. If an exception occurs in any of the clauses and is not handled, the exception is temporarily saved. The finally clause is executed. If there is a saved exception, it is re-raised at the end of the finally clause. If the finally clause raises another exception or executes a return or break statement, the saved exception is discarded:

例如:

def f():
    try:
        1/0
    finally:
        return

f() # No exception

def g():
    try:
        return 1
    finally:
        return 0

g() # 0

def h():
    try:
        raise NameError
    finally:
        raise TypeError

h() # TypeError