Naming a Block of Steps
Defining a function stores a named block of steps, and calling that name runs those steps wherever you invoke it. · 10 min
By now your programs are getting longer, and the same few lines keep showing up in more than one place. A function lets you write those lines once, give them a name, and run them again by name alone. There are two separate acts to keep straight: defining a function writes the steps down under a name, and calling it runs those steps. Define once; call as often as you need.
Guess before you learn
Python reads this file top to bottom. Does the word ready ever appear on the screen?
``
def setup():
print('ready')
print('go')
``
Only 'go' prints. Reading the def just stores setup's body under its name; the print inside waits for a call that never comes. If you expected 'ready' first, that is the most common first instinct — and keeping define and call separate is exactly what this folio is for.
9–12
3–5
A function is a set of steps you name once and use many times. First you define it — write the steps down under a name. Later you call it — say the name to make all those steps happen. Defining does not run the steps; calling does. Name it once, then call it as often as you like.
6–8
A function bundles a block of steps under a name. You write it with def name(): followed by an indented body. Reading a def only stores the block — Python does not run the body yet. To run it, you call the function by writing its name with parentheses, name(). Every call runs the stored body from the top, then hands control back to the line right after the call. Define once; call as many times as the program needs.
9–12
Defining a function and calling it are two separate moments. def greet(): binds the name greet to a block of code — the body is stored, not executed. A call, greet(), transfers control into that stored body, runs it to completion, then resumes at the statement after the call. This separation is what lets one definition serve many calls: the steps live in exactly one place, so fixing them once fixes every use. Reusing a name instead of repeating lines is your first real defense against copy-and-paste bugs.
K–2
Teach a puppy one trick and give it a name: sit. Say sit, and the puppy does the whole trick. A function is a named trick the computer learns once and does whenever you say its name.
Undergrad
A function definition creates a first-class object bound to a name in the enclosing namespace; def is an executable statement whose effect is that binding, not the running of the body. A call looks up the name, pushes a new stack frame, executes the body against it, and pops the frame on return, resuming the caller. Because the definition is a single object, every call shares one implementation — the substrate of the don't-repeat-yourself principle. A function you can name and call is also one you can pass around, store, and test on its own.
Postgrad
Viewed operationally, def evaluates to a closure — code paired with its defining environment — and binds it to a name. A call is a control transfer that allocates an activation record, installs parameter bindings (none here yet), runs the body, and returns control and a value to the continuation at the call site. The identity of a function as a reusable value, distinct from any single invocation, is what underwrites modular reasoning: verify the body once against a specification, then treat every call as that specification and ignore its internals.
function
A named block of steps. You define it once with def, and you call it — run its steps — by writing its name followed by parentheses.
Why is this true?
Why does reading a def line print nothing, even when the body contains a print?
Because def only stores the block under a name; it does not execute the body. The print inside runs only when the function is called. Defining and calling are separate acts, which is exactly what lets you define a function long before — and far from — where you use it.
Trace a program that defines, then calls twice — the steps fade as you master them
def cheer():. Does running the file print anything at this point?definition stored; body waits
cheer() runs the stored body top to bottom. How many lines does one call print, given the body is print('go') then print('team')?'go' then 'team'
cheer() runs the same body again. How many lines does the second call print?'go' then 'team' again
2 + 2
The real payoff of a name is reuse. When the same steps appear in three places, three copies means three places to fix when something changes. Fold them into one function and you fix the steps in one place, and every call sees the fix. Watch the order carefully, though: a call detours into the body, runs it, then comes back to exactly where it left off before continuing down the file.
So a function is a named block: define it once with def, call it by name whenever you want its steps to run, and control always returns to where the call was made. Right now every call does the exact same thing. Next folio changes that — you will feed values in through parameters and get one value back out with return, so a single definition can do different work each call.
Practice — new ink and old, interleaved
1.How many times does for i in range(2, 7): run its body?
2.Trace this loop. What is the value of i on the line right after the loop ends?
``
i = 0
while i < 3:
i = i + 1
``
3.What prints?
``
x = 7
if x > 10:
print('big')
elif x > 5:
print('medium')
else:
print('small')
``
4.How many numbers does range(1, 6) produce?
5.After name = input(), what type is name?
6.Review from folio 2: what is the type of "7", written with quotes?
7.How many times does the body of this loop run?
``
for i in range(2, 8):
print(i)
``
8.(2 < 3) and (3 < 2) evaluates to?
9.What prints, in order?
``
def tag():
print('mid')
print('a')
tag()
print('b')
``
10.How many lines does this print?
``
def ping():
print('!')
for i in range(3):
ping()
``