Functions
A name for a piece of work: give it inputs, get an answer back, and stop writing the same lines twice.
A name for a piece of work
A function is a block of code with a name. Write the work once, give it a name, and every later line calls the name instead of repeating the work. def starts the definition; the indented lines are what the name does.
Calling is the other half: greet("Ada") runs the block with Ada in place of the parameter. The brackets at the call site carry the inputs; the name in the definition is what the block calls them.
Defining, then calling
def greet(name):
return f"Hello, {name}!"
print(greet("Ada"))
print(greet("Grace"))Parameters in, return out
A parameter is the name a function gives to one of its inputs. name in the snippet stands for whatever the caller passes — one definition, and every name the program ever greets.
return hands a value back to whoever called. print shows something; return sends it somewhere it can be used again, which is why a function that returns its sentence can be printed, stored or measured, while one that only prints can do nothing else.
One answer for any temperature
The choice below works for one temperature. Wrap it in a function that takes a temperature and returns the advice, then print the advice for 12 and for 21.
Small pieces are easier to fix
The real gain is not fewer lines, it is fewer places for a mistake to hide. A function that does one thing can be read, tested and corrected on its own; a program that is one long run of lines has to be understood all at once.
A useful test when naming a function: if the honest name needs the word "and" in it, it is probably two functions pretending to be one.
The definition must be reached first
def is an instruction like any other. Python reaches it, builds the function, and gives the name to it; only then can a later line call that name. A call above the definition runs before the function exists, and the error names the call, not the definition.
That is why a file usually reads definitions first and the work underneath. It is not a rule about style but about order of execution: the definitions have to be reached before anything uses them. The same reasoning explains why a function body can name another function defined further down: the name is looked up when the call runs, not when the def line is read. The call still has to happen after that later definition has been reached.
A function is a value with a name
The name after def is an ordinary name bound to a function object. greet without brackets is that object; greet() is a call that runs it and hands back the answer. Passing greet to something else is therefore possible, which is how key=len works in the sorting chapter.
For now the practical part is the distinction at the call site. If a line prints something like <function greet at 0x...>, a pair of brackets is missing. If it prints None, the function ran but had nothing to return. Both are answers about the code, not about the greeting.
A function without a return still gives something back — the value None, which means "nothing in particular". That is the usual reason a printed call shows None.
The call and the definition meet at the brackets
Arguments are matched to parameters by position. In def describe(name, age):, the first value at the call fills name and the second fills age, so describe("Ada", 36) and describe(36, "Ada") are different programs — one of them will probably fail when it tries to use a number as text.
return ends the function at that line. Anything below it is unreachable, which is why a function normally keeps one return at the end, or puts returns inside branches that exclude each other. A function with no return still hands back None.
What happens inside stays inside
The names a function creates belong to it. A variable assigned inside describe exists while the call runs and is gone when it returns; the same name outside is a different name.
Parameters are local names too. That is what lets two functions both call their input value without interfering, and why a function has to return anything the caller needs.
Three function mistakes: writing greet instead of greet() gives you the function itself, not its answer; printing inside a function instead of returning leaves the caller with None; and a name created inside a function does not exist outside it.
Try these next
- Write
area(width, height)and call it with the arguments in the wrong order; fix the call, not the definition. - Add a second return inside an
ifand prove the lines below it never run. - Print a call to a function with no return, then add a return and print it again.
Area and perimeter
`area` is ready. Add `perimeter(width, height)` to return the distance around the rectangle, then print both results for a 4 by 7 rectangle.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
What is name in def greet(name):?
