【问题标题】:Why is this function decorator failing?为什么这个函数装饰器失败了?
【发布时间】:2018-09-12 05:59:22
【问题描述】:

这是我的代码:

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

我的理解是,包装器正在用紧跟在装饰器后面的函数“替换”自己。当我没有将参数传递给被装饰的函数时,这似乎可行,但在装饰器存在的情况下则不行。

【问题讨论】:

  • 你认为decorate 的回报是什么?
  • 我认为它返回了新函数。

标签: python parameters arguments decorator nonetype


【解决方案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 作为函数调用。

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

所以:

def decorate(func_to_decorate):

    def wrap(*args, **kwargs):

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

    return wrap

【讨论】:

  • 哦,有道理。感谢您的帮助和简洁的解释。
猜你喜欢
  • 1970-01-01
  • 2021-05-10
  • 2011-08-08
  • 1970-01-01
  • 2015-08-27
  • 2016-11-25
  • 2013-11-06
  • 2021-02-09
  • 1970-01-01
相关资源
最近更新 更多