How to Access All Arguments Passed to a Python Function
Python provides flexible ways to handle function arguments, allowing you to access both positional and keyword arguments within a function.
This guide explores how to access all arguments passed to a function, including named parameters, variable-length positional arguments (*args
), and variable-length keyword arguments (**kwargs
). We'll also cover how to use locals()
and inspect.signature()
.
Accessing Named Parameters, *args
, and **kwargs
This is the most common and recommended way to access arguments within a function.
def func(first, *args, **kwargs):
print(f"first: {first}") # Access named parameter directly
print(f"args: {args}") # Access positional arguments as a tuple
print(f"kwargs: {kwargs}") # Access keyword arguments as a dictionary
func('hello', 'arg1', 'arg2', name='tutorial', age=30)
Output:
first: hello
args: ('arg1', 'arg2')
kwargs: {'name': 'tutorial', 'age': 30}
- Named parameters:
first
is a named parameter. It's accessed directly by its name within the function. *args
: The*args
syntax collects all positional arguments after the named parameters into a tuple. This allows your function to accept an arbitrary number of positional arguments.**kwargs
: The**kwargs
syntax collects all keyword arguments (arguments passed asname=value
) into a dictionary. This lets your function accept arbitrary keyword arguments.
The order (named parameters, *args, **kwargs)
is important. You can omit *args
or **kwargs
if you don't need them, but if you use them, they must appear in this order.
*args
(Positional Arguments)
*args
allows a function to accept any number of positional arguments. These arguments are collected into a tuple:
def my_sum(*args):
print(args) # Output: (1, 2, 3, 4, 5)
return sum(args)
print(my_sum(1, 2, 3, 4, 5)) # Output: 15
- All positional arguments are grouped into a tuple.
**kwargs
(Keyword Arguments)
**kwargs
lets a function accept any number of keyword arguments. These arguments are collected into a dictionary:
def print_details(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_details(name="Alice", age=30, city="New York")
Output:
name: Alice
age: 30
city: New York
- All keyword arguments are grouped into a dictionary.
Combining Named Parameters, *args
, and **kwargs
A function can use a combination of all three:
def example(a, b, *args, c=None, **kwargs):
print("a:", a) # Output: a: 1
print("b:", b) # Output: b: 2
print("args:", args) # Output: args: (3, 4)
print("c:", c) # Output: c: default
print("kwargs:", kwargs) # Output: kwargs: {'d': 5, 'e': 6}
example(1, 2, 3, 4, c="default", d=5, e=6)
Using locals()
(Less Common)
The locals()
function returns a dictionary representing the current local symbol table. You can use it to access all arguments, but it's generally less clear and less flexible than using *args
and **kwargs
directly.
def func(first, *args, **kwargs):
all_arguments = locals()
print(all_arguments)
# Example Output:
# {'first': 'hello', 'args': ('arg1', 'arg2'), 'kwargs': {'name': 'tutorial', 'age': 30}}
my_variable = 'tutorialreference.com' # Local variable
print(locals())
# Example Output:
#{'first': 'hello', 'args': ('arg1', 'arg2'), 'kwargs': {'name': 'tutorial', 'age': 30},
# 'all_arguments': {...}, 'my_variable': 'tutorialreference.com'}
func('hello', 'arg1', 'arg2', name='tutorial', age=30)
- You have to call the
locals()
function before declaring any other variables in the scope.
While locals()
can be used to access arguments, it's generally not recommended for this purpose. It's less explicit and less readable than using *args
and **kwargs
. Also, locals()
includes all local variables, not just arguments.
Using inspect.signature()
(Advanced Introspection)
For advanced introspection (examining the structure of your code), the inspect
module can be useful. This is not typically needed for simply accessing arguments during normal function execution.
import inspect
def func(first, *args, **kwargs):
all_arguments = locals()
signature_values = inspect.signature(func).parameters.values()
all_argument_values = [
all_arguments[parameter.name] for parameter
in signature_values
]
print(all_argument_values)
# Output: ['hello', ('arg1', 'arg2'), {'name': 'tutorial', 'age': 30}]
print(inspect.signature(func))
# Output: (first, *args, **kwargs)
print(list(inspect.signature(func).parameters.keys()))
# Output: ['first', 'args', 'kwargs']
func('hello', 'arg1', 'arg2', name='tutorial', age=30)
- You can use the
inspect
module to check the signature of a function and the names of its parameters.
Passing All Arguments to Another Function
A common use case is to pass all arguments received by one function to another function. This is done elegantly using *args
and **kwargs
:
def concat(first, second, third):
return first + second + third
def funcA(*args, **kwargs):
print(args) # Output: ('tutorial', 'reference', '.com')
print(kwargs) # Output: {}
result = concat(*args, **kwargs) # Unpack args and kwargs
print(result) # Output: tutorialreference.com
return result
funcA('tutorial', 'reference', '.com')
*args
and**kwargs
capture all of the arguments passed tofuncA
.- The captured arguments can then be passed to another function using
*args
and**kwargs
which unpacks the arguments. - This approach is more explicit, readable, and therefore recommended.
Alternatively, you can unpack the arguments stored in locals()
dictionary to achieve the same:
def concat(first, second, third):
return first + second + third
def funcA(first, second, third):
print(locals()) # Output: {'first': 'tutorial', 'second': 'reference', 'third': '.com'}
result = concat(**locals()) # Unpack the result from locals()
print(result) # Output: tutorialreference.com
return result
funcA('tutorial', 'reference', '.com')