Search code examples
pythondictionarydecoratorargskeyword-argument

How do we use *args and **kwargs with decorators


i don't get why are we doing that args[0]["valid"] instead of just args["valid"]

 user1 = {
    'name': 'Sorna',
    'valid': True
}

def authenticated(fn):
  def wrapper(*args, **kwargs):
    if args[0]['valid']== True: #if args['valid']== True:
        return fn(*args, **kwargs)
  return wrapper

@authenticated
def message_friends(user):
    print('message has been sdent')

message_friends(user1)

Solution

  • *args are always passed as tuple, so you need to use an index to access the contents:

    def authenticated(fn):
      def wrapper(*args, **kwargs):
        print('A', args)
        print('K', kwargs)
        if args[0]['valid']== True:
            return fn(*args, **kwargs)
      return wrapper
    

    Out:

    A ({'name': 'Sorna', 'valid': True}, )
    K {}
    

    Alternatively, you could pass user1 as kwargs to get rid of the indexes:

    def authenticated(fn):
      def wrapper(*args, **kwargs):
        print('A', args)
        print('K', kwargs)
        if kwargs['valid']== True:
            return fn(*args, **kwargs)
      return wrapper
    
    @authenticated
    def message_friends(**user):
        print('message has been sent to %s' % user['name'])
    
    message_friends(**user1)
    

    Out:

    A ()
    K {'name': 'Sorna', 'valid': True}
    message has been sent to Sorna