Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why and how __call__ is invoked in python decorators

class myDecorator(object):

    def __init__(self, f):
        print "inside myDecorator.__init__()"
        f() # Prove that function definition has completed

    def __call__(self):
        print "inside myDecorator.__call__()"

@myDecorator
def aFunction():
    print "inside aFunction()"

def main():
    print "main starts....."
    aFunction()
    print "main ends....."

Output :

inside myDecorator.__init__()
inside aFunction()
main starts.....
inside myDecorator.__call__()
main ends.....

I could not understand following points about above code:

  1. Why "main starts...." is not first line to be printed?

  2. Suppose if i'm returning some value from aFunction() then it would not be available in place of its call because aFunction() is replaced with inside myDecorator.__call__() not inside aFunction().

like image 933
navyad Avatar asked Feb 16 '23 08:02

navyad


1 Answers

The decorator syntax:

@myDecorator
def aFunction():
    …

is equivalent to this:

def aFunction():
    …
aFunction = myDecorator(aFunction)

If myDecorator is a class, then you would expect __init__ to get called when the function is defined. The instance of the class is then used in place of the function. When you call it, you would expect __call__ to be called, so that’s where the call to f() should go.

like image 163
Josh Lee Avatar answered Mar 04 '23 06:03

Josh Lee