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

时间:2018-04-03 01:51:49

标签: python parameters arguments decorator nonetype

这是我的代码:

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

我的理解是包装器正在用装饰器后面的函数“替换”它自己。当我没有将参数传递给正在装饰的函数时,这似乎有效,但不是装饰器存在。

1 个答案:

答案 0 :(得分:1)

你的装饰师有两个问题。

首先,有一个缩进错误:

def decorate(func_to_decorate):

    def wrap(*args, **kwargs):

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

return wrapwrap函数体的一部分,而不是decorate函数体的一部分。因此,decorate没有return语句,这意味着它返回None。因此,您看到错误:装饰器实际上是用它返回的包装器“替换”包装函数 - 但该包装器是None,因此您最终尝试将None作为函数调用。 / p>

与此同时,你似乎明白wrap应该返回一些东西,但肯定不应该是本身。通常,您要返回的是包装函数(或该结果的某些后处理版本)的结果。在你的测试中,你只是试图包装一个仅用于副作用的函数,更不用说由于你的第一个问题你永远不会调用包装器,所以你不会注意到这个问题,但是你还想修理它。

所以:

def decorate(func_to_decorate):

    def wrap(*args, **kwargs):

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

    return wrap