为什么这个函数装饰器失败了?

Why is this function decorator failing?

这是我的代码:

name    = "Arthur"
message = "Hello!"

def decorate(func_to_decorate):

    def wrap(*args, **kwargs):

        print           ("........................")
        func_to_decorate(*args, **kwargs)
        print           ("........................")
        return wrap


@decorate
def send_message(your_name="unassigned", your_message="blank"):

    print(your_name)
    print(your_message)

send_message(name, message)

我的错误在第 20 行:

send_message(name, message)
TypeError: 'NoneType' object is not callable

我的理解是包装器是 "replacing" 本身,函数紧跟在装饰器之后。当我没有将参数传递给正在装饰的函数但没有装饰器时,这似乎有效。

你的装饰器有两个问题。

首先,有一个缩进错误:

def decorate(func_to_decorate):

    def wrap(*args, **kwargs):

        print           ("........................")
        func_to_decorate(*args, **kwargs)
        print           ("........................")
        return wrap

return wrapwrap 函数体的一部分,而不是 decorate 函数体的一部分。所以,decorate 没有 return 语句,这意味着它 returns None。因此,您看到的错误是:装饰器实际上是 "replacing" 带有包装器的包装函数 returns——但包装器是 None,所以您最终尝试调用 None作为函数。

同时,您似乎明白 wrap 应该 return 某些东西,但绝对不应该 本身 。通常,您想要 return 的是包装函数的结果(或该结果的某些 post-processed 版本)。在你的测试中,你只是想包装一个只用于 side-effects 的函数,更不用说你因为第一个问题而永远不会调用包装器,所以你还不会注意到这个问题, 但你还是想修复它。

所以:

def decorate(func_to_decorate):

    def wrap(*args, **kwargs):

        print           ("........................")
        retval = func_to_decorate(*args, **kwargs)
        print           ("........................")
        return retval

    return wrap