Home  >  Q&A  >  body text

python - Using __call__ to implement decorator functions

Use __call__ of a class to implement a decorator, as shown in the following code



class Check(object):
    def __init__(self, name):
        self.name = name

    def __call__(self, func):

        print "1111111111"

        def _decorator(*args, **kwargs):
            print "2222222222"
            return func(*args, **kwargs)
          

If you use this class as a decorator to decorate a function.

@Check("param")
def param_check(request):
    "python code....."
    return Response("ok")

Here comes the problem. Start a django or any other python process. When executing this param_check route, print "1111111111" is only printed for the first time, and 1111111111111 is not printed when called later.
And print "2222222222" is printed every time. My understanding is that __call__ is defining this decorator for the first time, so it is only executed once. It has been defined when requested again later, and only the function body part is executed, which is the print 222222222 part. Who knows the features of this python decorator

某草草某草草2692 days ago837

reply all(1)I'll reply

  • 迷茫

    迷茫2017-06-28 09:26:02

    Actually, there is something to note when using class decorators. Class decorators with parameters and without parameters are actually different

    Class decorator without parameters

    If you create a decorator without parameters, the decorated method will be passed to the decorator's constructor (__init__), and then when the decorated function is called, the decorator's __call__() method will be executed. .

    class Check(object):
    
        def __init__(self, func):
            self.func = func
    
        def __call__(self, *args):
    
            print("111111")
            self.func(*args)
            print("222222")
    
    @Check
    def param_check(request):
        print(request)
    
    
    
    param_check('hello')
    param_check('world')
    
    111111
    hello
    222222
    111111
    world
    222222

    It should be noted that during the decoration phase, the __init__ function is executed, and when the decorated method is called, __call__ is executed.

    Class decorator with parameters

    class Check(object):
        def __init__(self, name):
            self.name = name
    
        def __call__(self, func):
    
            print ("1111111111")
    
            def decorator(*args, **kwargs):
                print ("2222222222")
                return func(*args, **kwargs)
            return decorator
    
    @Check('parm')
    def param_check():
        print('Hello')
    
    param_check()
    param_check()

    Output:

    1111111111
    2222222222
    Hello
    2222222222
    Hello

    It can be clearly seen that __call__ will only be called once during the decoration phase

    If you want to know more details, please see here: http://www.artima.com/weblogs...

    reply
    0
  • Cancelreply