Varghab Shib
Varghab Shib

Reputation: 11

Could someone make me understand the algorithm running behind this in the most detailed way possible?

I know dec1() is a decorator and decorates who_is_nimo() function. There are several things at which I'm confused.

  1. Can't we decorate the function without creating nowexec() function inside dec1(func1)? I tried doing like this and it exactly give the same output like before(different from the main code).
def dec1(func1):
    print("Executing Now!")
    func1()
    print("Executed!")

@dec1
def who_is_nimo():
    print("Nimo")


who_is_nimo
  1. If we run who_is_nimo(without parenthesis) and return nowexec()(With parenthesis), then also the output is same. What exactly is going here?

Main Code:

def dec1(func1):
    def nowexec():
        print("Executing Now!")
        func1()
        print("Executed!")
    return nowexec

@dec1
def who_is_nimo():
    print("Nimo")


who_is_nimo()

Upvotes: 1

Views: 52

Answers (1)

chepner
chepner

Reputation: 531075

Decorator syntax is syntactic sugar for function application; basically,

@dec1
def who_is_nimo():
    print("Nimo")

is equivalent to

def who_is_nimo():
    print("Nimo")


who_is_nimo = dec1(who_is_nimo)

So what is the return value of dec1?

In your first case, it's whatever its argument returns when called. That is, ignoring the output produced by print,

who_is_nimo = who_is_nimo()

In your second case, dec1 creates a new function each time it is called, and that function keeps a reference to (i.e., closes over) the argument to dec1. As a result, who_is_nimo is bound to a new function that, when called, calls the original function that was bound to who_is_nimo. With a little bit of renaming, it has the same effect as

def who_is_nimo():
    print("Nimo")

tmp = who_is_limo  # Second reference to function currently bound to who_is_nimo

def nowexec():
    print("Executing Now!")
    tmp()
    print("Executed!")

who_is_nimo = now_exec

The main difference is that here, tmp is a global variable that can easily be changed, affecting how now_exec behaves. With the decorator, func1 is a ncn-local variable that is part of the definition of now_exec, and cannot be (easily) changed.

Upvotes: 1

Related Questions