装饰器错误:NoneType对象不可调用 [英] Decorator error: NoneType object is not callable

查看:116
本文介绍了装饰器错误:NoneType对象不可调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我这样写了一个函数装饰器:

I wrote a function decorator like this:

def tsfunc(func):
    def wrappedFunc():
        print '%s() called' % func.__name__
        return func()
    return wrappedFunc()

@tsfunc
def foo():
    pass

foo()  # to get it work, use foo instead of foo()
foo()

我收到以下错误消息:

foo() called
Traceback (most recent call last):
  File "decorator.py", line 11, in <module>
    foo()
TypeError: 'NoneType' object is not callable

I通过将 foo()替换为 foo来使其工作。但是我仍然没有得到预期的结果:

I get it work by replacing "foo()" with "foo". but I still didn't get the result I expected:

foo() called

好像 foo 函数仅被调用一次。

seems like the foo function is only called once.

请帮助我理解为什么会这样。

Please help me understand why this is happening.

推荐答案

您应该返回包装函数本身,不是其结果

You should return the wrapper function itself, not its result:

def tsfunc(func):
    def wrappedFunc():
        print '%s() called' % func.__name__
        return func()
    return wrappedFunc   # Do not call the function, return a reference instead

装饰器将装饰物替换为装饰器的返回值:

Decorators replace the decorated item with the return value of the decorator:

@tsfunc
def foo():
    # ....

等效于:

def foo():
    # ....
foo = tsfunc(foo)

扩展为(在您的代码中):

which expands to (in your code):

foo = wrappedFunc()

所以您要替换函数 foo 包含 wrappedFunc()调用的结果,而不是 wrappedFunc 本身。

so you were replacing the function foo with the result of the wrappedFunc() call, not with wrappedFunc itself.

这篇关于装饰器错误:NoneType对象不可调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆