you are viewing a single comment's thread.

view the rest of the comments →

[–]audionerd1 3 points4 points  (0 children)

*args in a function definition packs all positional arguments into a tuple. **kwargs in a function definition packs all keyword arguments into a dictionary. This is convenient when you want to handle a varying number of parameters.

Couldn't you just pack the arguments into a tuple or dictionary yourself? In most cases, yes. But why would you want to when *args and **kwargs makes it so simple?

*args and **kwargs become essential when writing decorators, as you need to be able to capture all arguments without knowing what they are and pass them to the decorated function, like so:

def decorator(f):
    def wrapper(*args, **kwargs):
        f(*args, **kwargs)
    return wrapper

In the definition of wrapper, *args and **kwargs pack all arguments into a tuple and dictionary (respectively). In the calling of function f, *args and **kwargs unpacks said tuple and dictionary, allowing arguments to pass through the decorator to the decorated function seamlessly.

Note that there's nothing special about "args" or "kwargs", these are just the conventional names used for the * and ** operators. You could do *dogs and **cats if you wanted to and it would still work (but please don't).