Search code examples
pythonfunctiondecorator

Decorator won't work: 'NoneType' object is not callable


import numpy as np

def multi_print(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for z in np.arange(n):
                print(func(*args))

@multi_print(2)   
def if_num(x):
    if x == 1:
        return 'abc'
    else:
        return 'def'

if_num(3)

I am trying to just play around with how decorators interact with functions. When I run this block of code, I get a 'NoneType' object is not callable error. Wasn't sure why. I would expect the above code to print "def" two times.


Solution

  • Your decorator and wrapper don't return anything. A decorator with arguments should return a decorator, and the decorator should return the wrapped function. The fix:

    import numpy as np
    
    def multi_print(n):
        def decorator(func):
            def wrapper(*args, **kwargs):
                for z in np.arange(n):
                    print(func(*args, **kwargs)) # should pass on kwargs, too
            return wrapper
        return decorator
    
    @multi_print(2)   
    def if_num(x):
        if x == 1:
            return 'abc'
        else:
            return 'def'
    
    if_num(3)
    

    Output:

    def
    def