Hiprup

What are *args and **kwargs in Python?

*args and **kwargs let a Python function accept a variable number of arguments. The * and ** are the actual language syntax; args and kwargs are conventional names — you can use any identifier, but sticking to the convention keeps code readable.

  • *args — collects any extra positional arguments into a tuple.

  • **kwargs — collects any extra keyword arguments into a dict.

Example:

def describe(name, *args, **kwargs):
    print(name, args, kwargs)

describe("Alice", 30, "NYC", role="admin", active=True)
# Alice (30, 'NYC') {'role': 'admin', 'active': True}

# *args - variable positional arguments
def sum_all(*args):
    return sum(args)  # args is a tuple

print(sum_all(1, 2, 3))        # 6
print(sum_all(1, 2, 3, 4, 5))  # 15

# **kwargs - variable keyword arguments
def create_user(**kwargs):
    return kwargs  # kwargs is a dict

user = create_user(name='John', age=30, role='admin')
print(user)  # {'name': 'John', 'age': 30, 'role': 'admin'}

# Combined
def log(level, *args, **kwargs):
    print(f'[{level}]', *args)
    for key, value in kwargs.items():
        print(f'  {key}: {value}')

log('INFO', 'User logged in', user='john', ip='192.168.1.1')

# Unpacking
def add(a, b, c):
    return a + b + c

nums = [1, 2, 3]
print(add(*nums))         # Unpack list -> add(1, 2, 3)

params = {'a': 1, 'b': 2, 'c': 3}
print(add(**params))      # Unpack dict -> add(a=1, b=2, c=3)

# Keyword-only arguments (after *)
def fetch(url, *, timeout=30, retries=3):
    pass  # timeout and retries MUST be passed as keywords

fetch('http://api.com', timeout=10)  # OK
# fetch('http://api.com', 10)         # TypeError!

*args collects (1, 2, 3) into a tuple. **kwargs collects keyword arguments into a dict. The combined example shows all three: required (level), variable positional (*args), and variable keyword (**kwargs).

Unpacking reverses the process: *nums spreads a list, **params spreads a dict. Keyword-only parameters (after *) enforce named arguments.

Know the parameter order: positional, *args, keyword-only, *kwargs. The unpacking use ( and ** in function calls) is as important as the collection use (in definitions).

The keyword-only parameter pattern (after *) is a Python 3 feature that shows depth.