-1

I have following code from portal:

def decorator(*args, **kwargs):
        print("Inside decorator")

        def inner(func):

                # code functionality here
                print("Inside inner function")
                print("I like", kwargs['like'])

                func()

        # returning inner function
        return inner

@decorator(like = "geeksforgeeks")
def my_func():
        print("Inside actual function")

When I execute this file, I can see its printing statement, but I don't see any function call in code. Am I missing something? While following code does not make any function call?

def decorator(*args,**kwargs):
    def inner1(func):
        def inner2():
            print(args[0])
            print(kwargs['like'])
            print("nitin")
            func()
        return inner2
    return inner1

@decorator("sourav",like="priyansh")
def printpankaj():
    print("pankaj")
  • I suggest reading this great guide on decorators: https://stackoverflow.com/questions/739654/how-do-i-make-function-decorators-and-chain-them-together – Caridorc Apr 30 '23 at 13:24
  • Does this answer your question? [Decorators with parameters?](https://stackoverflow.com/questions/5929107/decorators-with-parameters) – jonrsharpe Apr 30 '23 at 13:27
  • @jonrsharpe if decorator(like = "geeksforgeeks") is a function call then why in few example I see seperate function call like my_func() , bit confuse here. – pankaj kushwaha Apr 30 '23 at 13:28
  • `my_func` is still also a function, which can be called. A piece of code can contain multiple calls to multiple functions. – jonrsharpe Apr 30 '23 at 13:28
  • if in same code I try to call my_func() in last , it says non type object not callable ? why it shows that error? – pankaj kushwaha Apr 30 '23 at 13:36
  • @jonrsharpe I just edited the Q, I have added one more example where I dont call any function and nothing getting called , I am not able to understand why there is difference in behaviour? – pankaj kushwaha Apr 30 '23 at 13:43
  • Your second example _also_ makes two function calls: to the factory, then the decorator. It just doesn't print anything when it does so. It's actually a better decorator because it _doesn't_ immediately invoke the decorated function. – jonrsharpe Apr 30 '23 at 13:45
  • @jonrsharpe I mean how come that it call the function and does not print() . If I put a seperate function call in last like printpankaj() , it print everything. So why in one case it choose not to print and in another function call it print? – pankaj kushwaha Apr 30 '23 at 13:48
  • It's not choosing anything. That's just how the code's written. Use a debugger (or e.g. https://pythontutor.com/) to step through it if you're unclear on the control flow. – jonrsharpe Apr 30 '23 at 13:49

1 Answers1

1

To understand it better first imagine that your code is like this:

def decorator(*args, **kwargs):
    def inner(func):

        # code functionality here
        print("Inside inner function")
        print("I like", kwargs['like'])

        func()

    # returning inner function
    return inner

@decorator(like="geeksforgeeks")
def my_func():
    print("Inside actual function")

When you are using a decorator the decorator function executes and returns a function which contains your original function that has been decorated. The goal of a decorator is to decorate your function. So it gets your function, include it in another function which the decorator wants (in your case a function with two print statements, and then return the newly created function. So when this function executes it runs the two print statements. As a result, the output of the above code would look like this:

Inside inner function
I like geeksforgeeks
Inside actual function

To conclude, your original function is wrapped in the inner function. In the inner function, first the two print statements get executed and the your original function gets executed. So the output would look like above.

Now, imagine that you have added another print statement at the beginning of the decorator function (just like the code you have provided in your question). Remember I told you that a decorator creates a function and returns it, that is because the decorator is a function itself. So when you include a print statement at the beginning of the decorator, it would print it even before wrapping the original function. So the first statement that gets printed is the print statement at the beginning of the decorator function. After that, the inner function is created and eventually, it will be executed.

So the output would look like this:

Inside decorator
Inside inner function
I like geeksforgeeks
Inside actual function

Now see your second code. The second program has an inner function which just returns a function. No execution of that function is provided. So the inner function is called and as a result, another function is returned WITHOUT calling it.

  • but where is the function call? So I posted 2 example in Q, in first I dont call any funtion even then it print , in second example decorator function not getting called until I call it specificly , why there is difference? – pankaj kushwaha Apr 30 '23 at 13:58
  • Ok Just saw your edit , thanks alot , now I got it. – pankaj kushwaha Apr 30 '23 at 14:03