Search code examples
pythonargskeyword-argument

*args and **kwargs Python


I'm working on an exercise, I tried to solve it, but no result, I had to look at the solution, in order to have an idea and repeat it, the problem, I am stuck, a little lost.

# Create an @authenticated decorator that only allows the function to run is user1 has 'valid' set to True:

 user1 = { 'name': 'Sorna',
           'valid': True }         #changing this will either run or not run the message_friends function.

Solution :

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

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

message_friends(user1)

I really don't get this part :

if args[0]['valid']:

My question is if user1 = dict, why can't i just use **kwards so i can just check if the value is True by calling only [valid]: where it comes from the args[0]?

Help, i'm really stuck with this..


Solution

  • The decorator can be written a bit more clearly to not use args[0], does this help you understand?

    def authenticated(fn):
        def wrapper(user, *args, **kwargs):
            if user['valid']:
                return fn(user, *args, **kwargs)
    
        return wrapper
    
    @authenticated
    def message_friends(user):
        print('message has been sent to', user['name'])
    
    message_friends({'name': 'Sorna', 'valid': True})
    message_friends({'name': 'Bob', 'valid': False})
    

    Now *args, **kwargs is only there to pass along any other arguments the decorated function might have.

    This is also more robust because it works whether user is passed positionally or as a keyword argument.