Decorator Error: Nonetype Object Is Not Callable
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"