A Function Is a Named Block of Steps
Any time you find yourself writing the same few lines more than once — or wanting to give a small chunk of logic a name — you're ready to write a function. Functions are the first real tool for managing complexity in a Python program.
The basic shape:
Breaking that down:
defis the keyword that starts a function definition.greetis the function name.(name)is the parameter list — the inputs the function takes.- The colon ends the header; the indented block below is the body.
greet("Ada")is a call. Python runs the body withnamebound to"Ada".
Functions stay dormant until called. Defining one doesn't run it. Calling it with greet("Ada") does.
Parameters and Arguments
The word parameter is the name inside the function definition. The word argument is the value passed in when you call. Not a big deal in casual conversation, but the distinction helps when reading error messages.
Here base and exponent are parameters. 2 and 10 are arguments. Python binds them in order: first argument to first parameter, and so on.
return: Sending a Value Back
print writes to the screen. return hands a value back to the caller so they can use it:
Without return, a function returns None by default:
return also exits the function immediately. You'll often see early returns used to bail out of edge cases before the main logic:
Early returns keep the main body from being deeply nested in if/else.
Default Arguments
A parameter can have a default value, used when the caller doesn't provide one:
All parameters with defaults must come after parameters without defaults. def f(a, b=1, c): is a syntax error.
The mutable default trap
This is the most famous Python gotcha. Watch:
You'd expect each call to start with an empty list. Instead, the default list is shared across calls, and items accumulate. Python evaluates the default once, when the function is defined, and reuses that single list forever.
The safe pattern is to use None as the default and create the list inside the function:
Now each call that doesn't pass items gets a fresh list. This rule applies to lists, dicts, sets — anything mutable.
Keyword Arguments
You can pass arguments by name rather than position. That lets you skip middle parameters and make long calls more readable:
Positional and keyword arguments can mix, but positionals have to come first:
Once a function has more than three or four parameters, favouring keyword arguments makes calls much easier to read.
Positional-Only and Keyword-Only Parameters
Python lets you mark some parameters as callable by position only (with /) or by keyword only (with *):
You don't need these on day one. They become useful when designing APIs and want to lock down how callers use your function.
Docstrings and Naming
The first line inside a function can be a docstring — a triple-quoted string Python treats as documentation:
Tools like help(), IDE tooltips, and documentation generators read the docstring automatically. A one-liner is much better than nothing.
And please, think about naming:
- Function names should be verbs:
fetch_profile,compute_total,is_valid. - Use
lower_snake_case. - Boolean-returning functions often start with
is_,has_, orcan_.
A good name makes the call site self-explanatory without needing a comment.
Pure Functions Are Easier to Reason About
A pure function returns the same output for the same input and doesn't have side effects — it doesn't modify global state, print to stdout (other than for debugging), or write to files.
Both have their place, but in code you want to reuse and test, push toward pure functions as much as you can.
A Small Working Example
A quick function that combines defaults, keyword arguments, and return:
Next: Flexible Argument Lists
Sometimes you don't know how many arguments a function will be called with — or you want to forward whatever arguments arrive to another function. *args and **kwargs handle that. That's the next page.
Frequently Asked Questions
How do I define a function in Python?
Use the def keyword, followed by the function name, parentheses for parameters, and a colon. The indented block below is the function body. Example: def greet(name): print(f'Hi, {name}').
What does return do in Python?
return sends a value back to whoever called the function. A function without an explicit return returns None automatically. Once return runs, the function exits immediately — any code after it in the same block is skipped.
What are default arguments in Python?
Default arguments let a parameter have a pre-set value that's used if the caller doesn't provide one. def greet(name='friend'): means greet() with no arguments uses 'friend'. Never use mutable defaults like [] — see below for the safer pattern.