Writing Python functions means knowing how to pass information into your code. This skill lets you build flexible programs that adapt as your needs change. Python offers several ways to handle function arguments, each with its own rules and practical uses. Getting comfortable with these options makes your functions easier to use and update as your projects expand.
What Are Function Arguments?
Arguments are the values you put inside the parentheses when you call a function. These values get assigned to the function's parameters, so your code can work with different data on each run. You can pass as many arguments as the function definition allows, using commas to separate them. The official Python Language Reference explains that a function call is an expression where positional and keyword arguments go to a callable object, and "a call always returns some value, possibly None, unless it raises an exception."
Types of Arguments in Python
- Positional arguments
- Keyword arguments
- Default arguments
- Arbitrary or variable-length arguments
Positional Arguments
With positional arguments, order is key. Each value you give matches the corresponding parameter in the function definition, in sequence. Changing the order changes which parameter gets which value. The Python documentation calls these positional-or-keyword parameters, but you can also set up positional-only parameters using the / marker, a feature added in Python 3.8 as described in PEP 570. Parameters before the slash must be supplied by position, not by name.
def greet(name, age):
print(f"hello {name},Are you {age} year old")
greet("Ajay", 20)In this example, "Ajay" goes to name and 20 to age. Swapping the order changes the output.
Keyword Arguments
Keyword arguments let you specify which parameter each value should go to by using the parameter name and an equals sign. This makes the order unimportant, as long as the names match the function definition. The ability to control which arguments may be passed by keyword and which by position was set in Python 3 through PEP 3102, written by Barry Warsaw. This change lets function authors design clearer APIs with less confusion.
def greet(name, age):
print(f"hello {name},Are you {age} year old")
greet(age=20, name="Ajay")Here, age=20 and name="Ajay" are matched by name, not by position. This approach makes code easier to read and helps avoid mistakes when functions have many parameters. The Python tutorial points out that keyword arguments must come after positional arguments in a call.
Default Arguments
Default arguments let you set a fallback value for a parameter in the function definition. If the caller skips that argument, Python uses the default. All default arguments must come after non-default ones in the parameter list. The Python tutorial says "the default value is evaluated only once" when the function is defined, not each time it runs. This can cause surprises if the default is a mutable object like a list or dictionary. The usual advice is to use None as a placeholder and create a new object inside the function if needed.
def greet(name="ajay", message):
print(f"Hello {name}, {message}!")
greet("harry")
greet("harry", "Goodbye")In this code, if name is not given, it defaults to "ajay". If both name and message are provided, the function uses those values. Putting a default argument before a required one will trigger a syntax error.
Arbitrary or Variable-Length Arguments
There are times when you do not know how many arguments a function will get. Python offers two special forms for this:
- *args: Collects extra positional arguments into a tuple.
- **kwargs: Collects extra keyword arguments into a dictionary.
The Python Standard Library documentation lists five kinds of parameter: POSITIONAL_ONLY, POSITIONAL_OR_KEYWORD, VAR_POSITIONAL (for *args), KEYWORD_ONLY, and VAR_KEYWORD (for **kwargs). The difference between *args and **kwargs matters because they collect different types of arguments and use different calling syntax. The same unpacking operators (* and **) can be used at the call site to expand iterables and mappings into arguments, as described in the Python tutorial.
def dynamic_function(*args, **kwargs):
print("Positional tuple:", args)
print("Keyword dictionary:", kwargs)
dynamic_function(1, 2, 3, status="active", role="admin")
# Output:
# Positional tuple: (1, 2, 3)
# Keyword dictionary: {'status': 'active', 'role': 'admin'}This method works well for functions that need to accept a flexible number of arguments, such as logging tools or data processing functions. The Python tutorial notes, "In a function call, unpacking arguments is also possible."
Special Argument Boundaries: Positional-Only and Keyword-Only
Python lets you control how arguments are supplied by using special symbols in the function definition:
- Positional-only (/): Parameters before the slash must be passed by position, not as keywords. This feature was added in Python 3.8, as detailed in PEP 570 by Larry Hastings, and helps maintain backward compatibility and reserve parameter names for future use.
- Keyword-only (*): Parameters after the asterisk must be passed as keyword arguments. This was introduced in Python 3 via PEP 3102, letting function authors specify which arguments must be passed by keyword, which improves clarity and reduces confusion.
def add(a, b, /, c):
print(a + b + c)
add(20, 30, c=20) # valid
add(a=20, 30, c=30) # invaliddef add(a, b, *, c):
print(a + b + c)
add(a=20, 30, c=30) # invalid
add(20, 30, c=20) # invalidUsing these boundaries clarifies how your function should be called and can prevent mistakes, especially in larger codebases or shared libraries. The Python documentation states that when a function is called, "the arguments are assigned to the parameters according to the rules described below," and incorrect calls raise exceptions such as TypeError if required arguments are missing, unexpected keywords are supplied, or a parameter gets multiple values. These rules make function interfaces clear and provide predictable diagnostics as programs grow.
