Python Function Parameters and Arguments

Learn the difference between parameters and arguments, how to pass values by position and by keyword, and the rules for default parameter values.

7 min read

Python function parameters and arguments form the bridge between the code that calls a function and the code that runs inside it. Parameters let you write a function once and have it operate on different data every time it is called. Arguments are the actual values that flow across that bridge from the caller into the function body. Understanding how Python matches arguments to parameters, and the different ways you can supply those arguments, is essential for writing functions that are flexible, predictable, and easy to call correctly.

The terms "parameter" and "argument" refer to two sides of the same interaction. The parameter is the variable name you write inside the parentheses when you define the function. The argument is the concrete value you supply when you call the function. In a definition like def double(n), the n is a parameter. In a call like double(5), the 5 is an argument. The distinction matters because parameters determine what the function expects, while arguments determine what it actually receives. Mismatches between the two are among the most common errors in beginner Python code, and Python's error messages for these mismatches are precise enough that you can fix them quickly once you know what to look for.

A function can accept any number of parameters, and each one gets its own name inside the function body. These parameter names are local variables that exist only during the function call. They do not conflict with variables outside the function that happen to have the same name, a topic covered in detail by the article on variable scope in Python. The key point for now is that parameters create a clean boundary: the function sees only its parameters and its own local variables, not the caller's variables, and the caller sees only the return value, not the function's internal state.

Positional arguments: matched by order

The simplest and most common way to pass arguments is by position. Python matches the first argument in the call to the first parameter in the definition, the second argument to the second parameter, and so on. This matching is purely positional; the names of the arguments on the caller's side do not matter, only their order:

pythonpython
def describe_pet(name, species):
    print(f"{name} is a {species}.")
 
describe_pet("Whiskers", "cat")

Python binds "Whiskers" to name and "cat" to species because those are the positions in which they appear. If you swapped the arguments and wrote describe_pet("cat", "Whiskers"), Python would bind "cat" to name and "Whiskers" to species, and the output would read "cat is a Whiskers." That is technically valid Python but not what you intended. Positional arguments require you to remember and respect the order of the parameters, and for functions with many parameters this order can be hard to keep straight without looking at the definition.

The number of positional arguments must match the number of required parameters exactly. Calling a function with one missing argument raises a TypeError that tells you which positional argument is missing. Calling it with one extra argument raises a TypeError that tells you the function takes a certain number of positional arguments but more were given. These error messages are precise and point you directly to the mismatch.

Keyword arguments: matched by name

Keyword arguments let you specify which parameter each argument belongs to by writing the parameter name followed by an equals sign and the value. This frees you from having to remember the exact parameter order, and it makes function calls self-documenting because each value is labeled with its purpose. Writing describe_pet(species="dog", name="Rex") produces the same result regardless of order because Python matches by name, not position.

This becomes especially powerful when combined with default parameter values. A function that accepts half a dozen parameters, most of which have sensible defaults, can be called with a single keyword argument while all the other parameters fall back to their defaults. This pattern appears throughout Python's standard library and is the recommended approach for designing functions that need to support many configuration options without forcing every caller to specify every option.

Mixing positional and keyword arguments

Python allows both positional and keyword arguments in the same call, but with a strict rule: positional arguments must come first, followed by keyword arguments. You cannot place a keyword argument before a positional one. Once you use a keyword argument, every subsequent argument in the same call must also be a keyword argument. This rule prevents ambiguity and is enforced by the parser, so you get a syntax error before your code even runs if you violate it.

A common beginner mistake is to pass the same parameter twice, once by position and once by keyword. Python detects this and raises a TypeError with the message "got multiple values for argument." This error protects you from accidentally overriding an argument in a way that would be easy to miss during code review.

Default parameter values

You can make a parameter optional by giving it a default value in the function definition. If the caller provides an argument for that parameter, the argument overrides the default. If the caller omits it, the default takes effect:

pythonpython
def describe_pet(name, species="cat"):
    print(f"{name} is a {species}.")
 
describe_pet("Whiskers")     # Uses default: cat
describe_pet("Rex", "dog")   # Overrides default: dog

All parameters with default values must appear after all required parameters. Writing def describe_pet(species="cat", name) is a syntax error because if a required parameter appeared after an optional one, the caller could not omit the optional parameter without also omitting the required one. The rule is simple: required parameters first, then optional ones with defaults.

The mutable default argument trap

The most notorious pitfall in Python function definitions involves using a mutable object, like a list or a dictionary, as a default parameter value. Default values are evaluated once when the function is defined, not each time the function is called. If the default is mutable and the function modifies it, that modification persists across future calls. A function that appends to a default list will accumulate items across calls, producing output that depends on the function's entire call history rather than just its current arguments.

The standard fix is to use None as the default and create the mutable object inside the function body. Each call that omits the argument gets a fresh object, and the function behaves predictably regardless of how many times it has been called before. This pattern is so common in Python codebases that linters flag mutable default arguments as potential bugs before the code even runs.

Parameter names should communicate intent

The parameter names you choose become part of the function's public interface because callers using keyword arguments will type those names directly. A parameter called n is fine for a mathematical function where the meaning is obvious from context, but a parameter called data is too vague for a function that processes user records. When a function accepts multiple parameters of the same type, descriptive names are essential: a file-copy function with parameters named source and destination is immediately clear about which string represents the origin and which represents the target.

Parameters that represent quantities should include units in their name if the unit is not obvious. A parameter named timeout_seconds is clearer than timeout, and max_retries is clearer than max because it specifies both the constraint type and the subject. These naming practices are not language requirements but readability habits that pay off every time you return to code you wrote months earlier. The article on common Python function mistakes covers this and several other parameter design pitfalls in more detail.

Rune AI

Rune AI

Key Insights

  • Parameters are the names in a function definition; arguments are the values passed in a function call.
  • Positional arguments are matched to parameters by order and must appear first in a call.
  • Keyword arguments are matched by name and can appear in any order after positional arguments.
  • Default parameter values make arguments optional and must be defined after all required parameters.
  • Never use mutable objects like lists or dictionaries as default values; use None and create the object inside the function body instead.
RunePowered by Rune AI

Frequently Asked Questions

What is the difference between a parameter and an argument in Python?

A parameter is the variable name listed inside the parentheses in a function definition. An argument is the actual value passed to the function when it is called. Parameters are placeholders; arguments are the concrete values that fill those placeholders at call time.

Can I mix positional and keyword arguments in the same function call?

Yes, but positional arguments must come before keyword arguments. Writing calculate_total(100, tax_rate=0.08) is valid. Writing calculate_total(price=100, 0.08) is a syntax error. Once you use a keyword argument, every argument after it must also be a keyword argument.

What happens if I pass the wrong number of arguments to a Python function?

Python raises a TypeError. If you pass too few arguments, the error message tells you which positional arguments are missing. If you pass too many, the error says the function takes a certain number of positional arguments but more were given. Default parameter values let you make some arguments optional, which avoids the error when callers omit them.

Conclusion

Parameters and arguments are the mechanism that lets functions operate on different data each time they are called. Positional arguments are matched by order, keyword arguments are matched by name, and default values let you make parameters optional. Understanding these rules gives you the precision to design function interfaces that are both flexible and clear.