Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Decorators - __call__ in class

I was trying to understand Python decorators and I was trying to write an equivalent program to this one:

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()")

print ("Finished decorating aFunction()")

aFunction()

The problem is I am not understanding how the __call__ method of class is being invoked by calling aFunction() in the end.

Is aFunction() being replaced by myDecorator.__call__(aFunction). Can you please help me? How would be an equivalent program without decorators?

Thanks!

like image 523
pinker Avatar asked Oct 21 '13 14:10

pinker


1 Answers

Hello The correct way to do this would be something like this you have a Metaclass > --- Decoratorclass > --> Actual Class

    class Meta(type):
        """ Metaclass  """

        def __call__(cls, *args, **kwargs):
            instance = super(Meta, cls).__call__(*args, **kwargs)
            return instance

        def __init__(cls, name, base, attr):
            super(Meta, cls).__init__(name, base, attr)


    class counted(metaclass=Meta):

        """ counts how often a function is called """

        def __init__(self, func):
            self.func = func

        def __call__(self, *args, **kwargs):
            print("Timer Start ")
            Tem = self.func(*args, **kwargs)
            print("Timer End {} ".format(Tem))
            return Tem


    class Test(object):

        def __init__(self, *args, **kwargs):
            pass

        @counted
        def methodA():
            print("Method A")
            return "1111"


    if __name__ == "__main__":
        obj = Test()
        obj.methodA()
like image 173
Soumil Nitin Shah Avatar answered Sep 19 '22 16:09

Soumil Nitin Shah