Skip to content Skip to sidebar Skip to footer

Decorator Error: Nonetype Object Is Not Callable

I wrote a function decorator like this: def tsfunc(func): def wrappedFunc(): print '%s() called' % func.__name__ return func() return wrappedFunc() @tsfunc

Solution 1:

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

deftsfunc(func):
    defwrappedFunc():
        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:

@tsfuncdeffoo():
    # ....

is equivalent to:

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

which expands to (in your code):

foo = wrappedFunc()

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

Solution 2:

You need to remove the parentheses in

return wrappedFunc

The decorator is supposed to return the wrapper function, not call it.

With this fix, the code produces:

foo() called
foo() called

Solution 3:

A little late , but hope this helps, Extending on why the answer provided is accepted

as the error states, 'NoneType' means that the instance/object we are trying to call has no type (it is not a function/int/boolean/class/instance ). Its type is just 'None' So to summarize, decorators are nothing but extended use of closures with functions being treated as first class citizens (You could get a detail view on closures It basically means a decorator expects a function to be returned , say a wrapper in most cases, with the original function being unaltered and being called withing the decorator

def tsfunc(func):
    def wrappedFunc():
        print '%s() called' % func.__name__
        returnfunc()
    returnwrappedFunc() -> Here the function isnot returned but called eventually

@tsfunc
def foo():
    pass

foo() - > calling this again doesnt make sense to trigger the decorator, since a reference for the method foo is enough. Hence foo works fine but foo() doesn't (method call has completed already but no valueis returned) If you try like this, you would see that the variable has 'None' type

def tsfunc(func):
        def wrappedFunc():
            print '%s() called' % func.__name__
            returnfunc()
        return wrappedFunc --  Here I made the correction
    
    @tsfunc
    def foo():
        pass
var1 = foo()
print(var1)

This what happened with the call to foo() when you had the incorrect way of calling the wrapper function rather than returning just the function

So for a decorator to function as per the norms, it should return a wrapper function with the original function being unaltered. And hence it should be rewritten as per the accepted answer

Solution 4:

you use this syntax

deftsfunc(func):
    defwrappedFunc():
        print'%s() called' % func.__name__
        return func()
    return wrappedFunc # not use wrappedFunc() becaues Because this function runs at the this time @tsfuncdeffoo():
    pass

foo()  # 

Post a Comment for "Decorator Error: Nonetype Object Is Not Callable"