1

I have a piece of code as follows:

def range_print(n, *args):
    for i in range(n):
        func(i)
@range_print(n=10)
def func(i):
    print(i)

I get:

TypeError                                 Traceback (most recent call last)
<ipython-input-4-b13e44263521> in <module>
      2     for i in range(n):
      3         func(i)
----> 4 @range_print(n=10)
      5 def func(i):
      6     print(i)

<ipython-input-4-b13e44263521> in range_print(n, *args)
      1 def range_print(n, *args):
      2     for i in range(n):
----> 3         func(i)
      4 @range_print(n=10)
      5 def func(i):

TypeError: 'NoneType' object is not callable

Later I solved the problem, but I don't know if there is a better way? I want to use decorators to make my code look cleaner.

def range_print(n, *args):
    def inner(func): # <----Why do I need this def to load func?
        for i in range(n):
            func(i)
    return inner
@range_print(n=10)
def func(i):
    print(i)

1 Answer 1

1

The reason why the function inner takes a function as a parameter, is that this is how the mechanics of Python work when you add a decorator like @range_print(n=10) to your function.

When you call your function, Python passes the function itself, together with its arguments, to the range_print decorator.

So in your case, the parameter named n in the range_print function signature is actually a function.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.