Python Functions
Estimated reading: 3 minutes 278 views

Python Arbitrary Arguments – Mastering *args and **kwargs

Introduction – Why Arbitrary Arguments Matter

When writing flexible, reusable functions, it’s often useful to accept any number of arguments. Python provides a simple and elegant way to do this with arbitrary arguments: *args and **kwargs.

These allow you to write functions that accept:

  • Any number of positional arguments using *args
  • Any number of keyword arguments using **kwargs

This is essential for building libraries, decorators, and APIs where input parameters can vary.

In this guide, you’ll learn:

  • How *args and **kwargs work
  • When and why to use them
  • Real-world examples
  • Best practices and common pitfalls

Syntax of Arbitrary Arguments

*args (Arbitrary Positional Arguments)

def function_name(*args):
    for arg in args:
        print(arg)

**kwargs (Arbitrary Keyword Arguments)

def function_name(**kwargs):
    for key, value in kwargs.items():
        print(key, value)

You can use both in a function, but *args must appear before **kwargs.


Example 1: Using *args

def add_all(*numbers):
    return sum(numbers)

print(add_all(2, 4, 6, 8))

Output:

20

Explanation:
All arguments are grouped into a tuple named numbers.


Example 2: Using **kwargs

def print_user_info(**info):
    for key, value in info.items():
        print(f"{key}: {value}")

print_user_info(name="Alice", age=30, city="New York")

Output:

name: Alice  
age: 30  
city: New York

Explanation:
All named arguments are stored in a dictionary called info.


Combining *args and **kwargs

def mixed_args(*args, **kwargs):
    print("Positional:", args)
    print("Keyword:", kwargs)

mixed_args(1, 2, 3, name="Bob", age=40)

Output:

Positional: (1, 2, 3)  
Keyword: {'name': 'Bob', 'age': 40}

Tip: Always place *args before **kwargs in function definitions.


Real-World Example: Configurable Logger

def log_message(level, *messages, **metadata):
    print(f"[{level}] ", end="")
    for msg in messages:
        print(msg, end=" ")
    if metadata:
        print(f"| Metadata: {metadata}")
    else:
        print()

log_message("INFO", "User logged in", "ID=123", user="admin", role="superuser")

Use Case: Useful for tools where you don’t know how much info you’ll receive.


Common Pitfalls

PitfallSolution
Mixing *args and **kwargs improperlyUse *args before **kwargs
Using default args after *argsDefine defaults before *args
Forgetting unpacking syntaxUse * and ** when calling functions

Best Practices

  • Name them *args and **kwargs by convention (but names can vary)
  • Use only when truly needed (don’t overuse!)
  • Use unpacking (* and **) when passing arguments to other functions
  • Document what your function expects if using arbitrary inputs

Summary – Key Takeaways

  • *args gathers extra positional arguments into a tuple
  • **kwargs gathers extra keyword arguments into a dictionary
  • Perfect for dynamic APIs, decorators, and flexible utilities
  • Maintain argument order: normal, *args, default, **kwargs

FAQ Section

Can I change the names from args and kwargs?

Yes, but it’s recommended to stick to convention for clarity.

What happens if I pass extra arguments without using *args or **kwargs?

You’ll get a TypeError saying too many arguments were given.

Can I unpack a list or dict when calling a function?

Yes!

func(*[1, 2, 3])
func(**{"name": "Alice", "age": 25})

Can I use *args without **kwargs and vice versa?

Yes. Use whichever fits your use case.


Share Now :
Share

Python Arbitrary Arguments

Or Copy Link

CONTENTS
Scroll to Top