Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Defining and Calling Python Functions Show
Throughout the previous tutorials in this series, you’ve seen many examples demonstrating the use of built-in Python functions. In this tutorial, you’ll learn how to define your own Python function. You’ll learn when to divide your program into separate user-defined functions and what tools you’ll need to do this. Here’s what you’ll learn in this tutorial:
Functions in PythonYou may be familiar with the mathematical concept of a function. A function is a relationship or mapping between one or more inputs and a set of outputs. In mathematics, a function is typically represented like this: Here, In programming, a function is a self-contained block of code that encapsulates a specific task or related group of tasks. In previous tutorials in this series, you’ve been introduced to some of the built-in functions provided by Python.
>>>
>>>
>>>
Each of these built-in functions performs a specific task. The code that accomplishes the task is defined somewhere, but you don’t need to know where or even how the code works. All you need to know about is the function’s interface:
Then you call the function and pass the appropriate arguments. Program execution goes off to the designated body of code and does its useful thing. When the function is finished, execution returns to your code where it left off. The function may or may not return data for your code to use, as the examples above do. When you define your own Python function, it works just the same. From somewhere in your code, you’ll call your Python function and program execution will transfer to the body of code that makes up the function. When the function is finished, execution returns to the location where the function was called. Depending on how you designed the function’s interface, data may be passed in when the function is called, and return values may be passed back when it finishes. The Importance of Python FunctionsVirtually all programming languages used today support a form of user-defined functions, although they aren’t always called functions. In other languages, you may see them referred to as one of the following:
So, why bother defining functions? There are several very good reasons. Let’s go over a few now. Abstraction and ReusabilitySuppose you write some code that does something useful. As you continue development, you find that the task performed by that code is one you need often, in many different locations within your application. What should you do? Well, you could just replicate the code over and over again, using your editor’s copy-and-paste capability. Later on, you’ll probably decide that the code in question needs to be modified. You’ll either find something wrong with it that needs to be fixed, or you’ll want to enhance it in some way. If copies of the code are scattered all over your application, then you’ll need to make the necessary changes in every location. A better solution is to define a Python function that performs the task. Anywhere in your application that you need to accomplish the task, you simply call the function. Down the line, if you decide to change how it works, then you only need to change the code in one location, which is the place where the function is defined. The changes will automatically be picked up anywhere the function is called. The abstraction of functionality into a function definition is an example of the Don’t Repeat Yourself (DRY) Principle of software development. This is arguably the strongest motivation for using functions. ModularityFunctions allow complex processes to be broken up into smaller steps. Imagine, for example, that you have a program that reads in a file, processes the file contents, and then writes an output file. Your code could look like this:
In this example, the main program is a bunch of code strung together in a long sequence, with whitespace and comments to help organize it. However, if the code were to get much lengthier and more complex, then you’d have an increasingly difficult time wrapping your head around it. Alternatively, you could structure the code more like the following:
This example is modularized. Instead of all the code being strung together, it’s broken out into separate functions, each of which focuses on a specific task. Those tasks are read, process, and write. The main program now simply needs to call each of these in turn. In life, you do this sort of thing all the time, even if you don’t explicitly think of it that way. If you wanted to move some shelves full of stuff from one side of your garage to the other, then you hopefully wouldn’t just stand there and aimlessly think, “Oh, geez. I need to move all that stuff over there! How do I do that???” You’d divide the job into manageable steps:
Breaking a large task into smaller, bite-sized sub-tasks helps make the large task easier to think about and manage. As programs become more complicated, it becomes increasingly beneficial to modularize them in this way. Namespace SeparationA namespace is a region of a program in which identifiers have meaning. As you’ll see below, when a Python function is called, a new namespace is created for that function, one that is distinct from all other namespaces that already exist. The practical upshot of this is that variables can be defined and used within a Python function even if they have the same name as variables defined in other functions or in the main program. In these cases, there will be no confusion or interference because they’re kept in separate namespaces. This means that when you write code within a function, you can use variable names and identifiers without worrying about whether they’re already used elsewhere outside the function. This helps minimize errors in code considerably. Hopefully, you’re sufficiently convinced of the virtues of functions and eager to create some! Let’s see how. Function Calls and DefinitionThe usual syntax for defining a Python function is as follows:
The components of the definition are explained in the table below:
The final item, The syntax for calling a Python function is as follows:
As usual, you’ll start with a small example and add complexity from there. Keeping the time-honored mathematical tradition in mind, you’ll call your first Python function
Here’s how this code works:
The sequence of execution (or
control flow) for When
Occasionally, you may want to define an empty function that does nothing. This is referred to as a stub, which is usually a temporary placeholder for a Python function that will be fully implemented at a later time. Just as a block in a
control structure can’t be empty, neither can the body of a function. To define a stub function, use the >>>
As you can see above, a call to a stub function is syntactically valid but doesn’t do anything. Argument PassingSo far in this tutorial, the functions you’ve defined haven’t taken any arguments. That can sometimes be useful, and you’ll occasionally write such functions. More often, though, you’ll want to pass data into a function so that its behavior can vary from one invocation to the next. Let’s see how to do that. Positional ArgumentsThe most straightforward way to pass arguments to a Python function is with positional arguments (also called required arguments). In the function definition, you specify a comma-separated list of parameters inside the parentheses: >>>
When the function is called, you specify a corresponding list of arguments: >>>
The parameters (
In some programming texts, the parameters given in the function definition are referred to as formal parameters, and the arguments in the function call are referred to as actual parameters: Although positional arguments are the most straightforward way to pass data to a function, they also afford the least flexibility. For starters, the order of the arguments in the call must match the order of the parameters in the definition. There’s nothing to stop you from specifying positional arguments out of order, of course: >>>
The function may even still run, as it did in the example above, but it’s very unlikely to produce the correct results. It’s the responsibility of the programmer who defines the function to document what the appropriate arguments should be, and it’s the responsibility of the user of the function to be aware of that information and abide by it. With positional arguments, the arguments in the call and the parameters in the definition must agree not only in order but in number as well. That’s the reason positional arguments are also referred to as required arguments. You can’t leave any out when calling the function: >>>
Nor can you specify extra ones: >>>
Positional arguments are conceptually straightforward to use, but they’re not very forgiving. You must specify the same number of arguments in the function call as there are parameters in the definition, and in exactly the same order. In the sections that follow, you’ll see some argument-passing techniques that relax these restrictions. Keyword ArgumentsWhen you’re calling a function, you can specify arguments in the form >>>
Referencing a keyword that doesn’t match any of the declared parameters generates an exception: >>>
Using keyword arguments lifts the restriction on argument order. Each keyword argument explicitly designates a specific parameter by name, so you can specify them in any order and Python will still know which argument goes with which parameter: >>>
Like with positional arguments, though, the number of arguments and parameters must still match: >>>
So, keyword arguments allow flexibility in the order that function arguments are specified, but the number of arguments is still rigid. You can call a function using both positional and keyword arguments: >>>
When positional and keyword arguments are both present, all the positional arguments must come first: >>>
Once you’ve specified a keyword argument, there can’t be any positional arguments to the right of it. To learn more about positional and keyword parameters, check out the Real Python course Exploring Special Function Parameters. Default ParametersIf a parameter specified in a Python
function definition has the form >>>
When this version of >>>
In summary:
Mutable Default Parameter ValuesThings can get weird if you specify a default parameter value that is a mutable object. Consider this Python function definition: >>>
>>>
The default value for parameter Everything makes sense so far. Now, what would
you expect to happen if >>>
Oops! You might have expected each subsequent call to also return the singleton list In Python, default parameter values are defined only once when the function is defined (that is, when the
You can demonstrate this with >>>
The object identifier displayed confirms that, when As a workaround, consider using a default argument value that signals no argument has been specified. Most any value would work, but >>>
Note how this ensures that Pass-By-Value vs Pass-By-Reference in PascalIn programming language design, there are two common paradigms for passing an argument to a function:
Other mechanisms exist, but they are essentially variations on these two. In this section, you’re going to take a short detour from Python and briefly look at Pascal, a programming language that makes a particularly clear distinction between these two. Here’s what you need to know about Pascal syntax:
With that bit of groundwork in place, here’s the first Pascal example:
Here’s what’s going on:
Running this code generates the following output:
In this example, Now, compare this with the next example:
This code is identical to the first example, with one change. It’s the presence of the word The output from this code is the same as before, except for the last line:
Again, In many programming languages, that’s essentially the distinction between pass-by-value and pass-by-reference:
The reason why comes from what a reference means in these languages. Variable values are stored in memory. In Pascal and similar languages, a reference is essentially the address of that memory location, as demonstrated below: In the diagram on the left, In the diagram on the right, Pass-By-Value vs Pass-By-Reference in PythonAre parameters in Python pass-by-value or pass-by-reference? The answer is they’re neither, exactly. That’s because a reference doesn’t mean quite the same thing in Python as it does in Pascal. Recall that in Python, every piece of data is an object. A reference points to an object, not a specific memory location. That means assignment isn’t interpreted the same way in Python as it is in Pascal. Consider the following pair of statements in Pascal: These are interpreted this way:
By contrast, in Python, the analogous assignment statements are as follows: These assignment statements have the following meaning:
In Python, when you pass an argument to a function, a similar rebinding occurs. Consider this example: >>>
In the main program, the statement However, when the statement You can confirm all this using >>>
When Argument passing in Python is somewhat of a hybrid between pass-by-value and pass-by-reference. What gets passed to the function is a reference to an object, but the reference is passed by value. The key takeaway here is that a Python function can’t change the value of an argument by reassigning the corresponding parameter to something else. The following example demonstrates this: >>>
Here, objects of type Does that mean a Python function can never modify its arguments at all? Actually, no, that isn’t the case! Watch what happens here: >>>
In this case, the argument to However, >>>
Here, Argument Passing SummaryArgument passing in Python can be summarized as follows. Passing an immutable object, like an Passing a mutable object such as a Side EffectsSo, in Python, it’s possible for you to modify an argument from within a function so that the change is reflected in the calling environment. But should you do this? This is an example of what’s referred to in programming lingo as a side effect. More generally, a Python function is said to cause a side effect if it modifies its calling environment in any way. Changing the value of a function argument is just one of the possibilities. When they’re hidden or unexpected, side effects can lead to program errors that are very difficult to track down. Generally, it’s best to avoid them. The return StatementWhat’s a Python function to do then? After all, in many cases, if a function doesn’t cause some change in the calling environment, then there isn’t much point in calling it at all. How should a function affect its caller? Well, one possibility is to use function return values. A
Exiting a FunctionWithin a function, a >>>
In this example, the However, >>>
The first two calls to This sort of paradigm can be useful for error checking in a function. You can check several error conditions at
the start of the function, with
If none of the error conditions are encountered, then the function can proceed with its normal processing. Returning Data to the CallerIn addition to exiting a function, the
>>>
Here, the value of the expression A function can return any type of object. In Python, that means pretty much anything whatsoever. In the calling environment, the function call can be used syntactically in any way that makes sense for the type of object the function returns. For example, in this code, >>>
In the next example, >>>
Here, >>>
If multiple comma-separated expressions are specified in a >>>
When no return value is given, a Python function returns the special Python value >>>
The same thing happens if the function body doesn’t contain a >>>
Recall that Since functions that exit through a bare >>>
Here, calls to both Revisiting Side EffectsSuppose you want to write a function that takes an integer argument and doubles it. That is, you want to pass an integer variable to the function, and when the function returns, the value of the variable in the calling environment should be twice what it was. In Pascal, you could accomplish this using pass-by-reference:
Executing this code produces the following output, which verifies that
In Python, this won’t work. As you now know, Python integers are immutable, so a Python function can’t change an integer argument by side effect: >>>
However, you can use a return value to obtain a similar effect. Simply write >>>
This is arguably preferable to modifying by side effect. It’s very clear that Still, even in cases where it’s possible to modify an argument by side effect, using a return value may still be clearer. Suppose you want to double every item in a list. Because lists are mutable, you could define a Python function that modifies the list in place: >>>
Unlike However, you can also write >>>
Either approach works equally well. As is often the case, this is a matter of style, and personal preferences vary. Side effects aren’t necessarily consummate evil, and they have their place, but because virtually anything can be returned from a function, the same thing can usually be accomplished through return values as well. Variable-Length Argument ListsIn some cases, when you’re defining a function, you may not know beforehand how many arguments you’ll want it to take. Suppose, for example, that you want to write a Python function that computes the average of several values. You could start with something like this: >>>
All is well if you want to average three values: However, as you’ve already seen, when positional arguments are used, the number of arguments passed must agree with the number of parameters declared. Clearly then,
all isn’t well with this implementation of >>>
You could try to define >>>
This allows for a variable number of arguments to be specified. The following calls are at least syntactically correct:
But this approach still suffers from a couple of problems. For starters, it still only allows up to five arguments, not an arbitrary number. Worse yet, there’s no way to distinguish between the arguments that were specified and those that were allowed to default. The function has no way to know how many arguments were actually passed, so it doesn’t know what to divide by: >>>
Evidently, this won’t do either. You
could write >>>
At least this works. It allows an arbitrary number of values and produces a correct result. As an added bonus, it works when the argument is a tuple as well: >>>
The drawback is that the added step of having to group the values into a list or tuple is probably not something the user of the function would expect, and it isn’t very elegant. Whenever you find Python code that looks inelegant, there’s probably a better option. In this case, indeed there is! Python provides a way to pass a function a variable number of arguments with argument tuple packing and unpacking using the asterisk ( Argument Tuple PackingWhen a parameter name in a Python function definition is preceded by an asterisk ( >>>
In the definition of Using tuple packing, you can clean up >>>
Better still, you can tidy it up even further by replacing the >>>
Now, Still, depending on how this code will be used, there may still be work to do. As
written, >>>
To be as robust as possible, you should add code to check that the arguments are of the proper type. Later in this tutorial series, you’ll learn how to catch exceptions like Argument Tuple UnpackingAn analogous operation is available on the other side of the equation in a Python function call. When an argument in a function call is preceded by an asterisk
( >>>
In this example, Although
this type of unpacking is called tuple unpacking, it doesn’t only work with tuples. The asterisk ( >>>
You can even use tuple packing and unpacking at the same time: >>>
Here, Argument Dictionary PackingPython has a similar operator, the double asterisk ( >>>
In this case, the arguments Argument Dictionary UnpackingArgument dictionary
unpacking is analogous to argument tuple unpacking. When the double asterisk ( >>>
The items in the dictionary >>>
In fact, check this out: >>>
Here, Putting It All TogetherThink of All three—standard positional parameters, >>>
This provides just about as much flexibility as you could ever need in a function interface! Multiple Unpackings in a Python Function CallPython version 3.5 introduced support for additional unpacking generalizations, as outlined in PEP 448. One thing these enhancements allow is multiple unpackings in a single Python function call: >>>
You can specify multiple dictionary unpackings in a Python function call as well: >>>
By the way, the unpacking operators >>>
Here, the literal lists Keyword-Only ArgumentsA Python function in version 3.x can be defined so that it takes keyword-only arguments. These are function arguments that must be specified by keyword. Let’s explore a situation where this might be beneficial. Suppose you want to write a Python function that takes a variable
number of string arguments, concatenates them together separated by a dot ( >>>
As it stands, the output prefix is hard-coded to the string >>>
This works as advertised, but there are a couple of undesirable things about this solution:
You might think you could overcome the second issue by specifying a parameter with a default value, like this, perhaps: >>>
Unfortunately, this doesn’t work quite right. >>>
What if you try to specify >>>
As you’ve seen previously, when both types of arguments are given, all positional arguments must come before any keyword arguments. However, you can’t specify it last either: >>>
Again, Keyword-only parameters help solve this dilemma. In the function definition, specify >>>
In that case, >>>
Note that this is only possible in Python 3. In
versions 2.x of Python, specifying additional parameters after the Keyword-only arguments allow a Python function to take a variable number of arguments, followed by one or more additional options as keyword arguments. If you wanted to modify >>>
If a keyword-only parameter is given a default value in the function definition (as it is in the example above), and the keyword is omitted when the function is called, then the default value is supplied: >>>
If, on the other hand, the parameter isn’t given a default value, then it becomes required, and failure to specify it results in an error:
>>>
What if you want to define a Python function that takes a keyword-only argument but doesn’t take a variable number of positional arguments? For example, the following function performs the specified operation on two numerical arguments: >>>
If you wanted to make >>>
The problem with this solution is that >>>
In this example, the extra argument shouldn’t be there (as the argument itself announces). Instead of quietly succeeding, it should really result in an error. The fact that it doesn’t is untidy at best. At worst, it may cause a result that appears misleading: To remedy this, version 3 allows a variable argument parameter in a Python function definition to be just a bare asterisk ( >>>
The bare variable argument parameter Positional-Only ArgumentsAs of Python 3.8, function parameters can also be declared positional-only, meaning the corresponding arguments must be supplied positionally and can’t be specified by keyword. To designate some parameters as positional-only, you specify a bare slash ( >>>
This means that the following calls are valid: >>>
The following call to >>>
The positional-only and keyword-only designators may both be used in the same function definition: >>>
In this example:
For more information on positional-only parameters, see the Python 3.8 release highlights. DocstringsWhen the first statement in the body of a Python function is a string literal, it’s known as the function’s docstring. A docstring is used to supply documentation for a function. It can contain the function’s purpose, what arguments it takes, information about return values, or any other information you think would be useful. The following is an example of a function definition with a docstring: >>>
Technically, docstrings can use any of Python’s quoting mechanisms, but the recommended convention is to triple-quote using double-quote characters
( Multi-line docstrings are used for lengthier documentation. A multi-line docstring should consist of a summary line, followed by a blank line, followed by a more detailed description. The closing quotes should be on a line by themselves: >>>
Docstring formatting and semantic conventions are detailed in PEP 257. When a docstring is defined, the Python interpreter assigns it to a special attribute of the function called You can
access a function’s docstring with the expression >>>
In the interactive Python interpreter, you can type >>>
It’s considered good coding practice to specify a docstring for each Python function you define. For more on docstrings, check out Documenting Python Code: A Complete Guide. Python Function AnnotationsAs of version 3.0, Python provides an additional feature for documenting a function called a function annotation. Annotations provide a way to attach metadata to a function’s parameters and return value. To add an annotation to a Python function parameter, insert a colon ( >>>
The annotation for parameter The Python interpreter creates a dictionary from the annotations and assigns them to another special dunder
attribute of the function called >>>
The keys for the parameters are the parameter names. The key for the return value is the string >>>
Note that annotations aren’t restricted to string values. They can be any expression or object. For example, you might annotate with type objects: >>>
An annotation can even be a composite object like a list or a dictionary, so it’s possible to attach multiple items of metadata to the parameters and return value: >>>
In the example above, an annotation is attached to the parameter If you want to assign a default value to a parameter that has an annotation, then the default value goes after the annotation: >>>
What do annotations do? Frankly, they don’t do much of anything. They’re just kind of there. Let’s look at one of the examples from above again, but with a few minor modifications: >>>
What’s going on here? The annotations for Annotations don’t impose any semantic restrictions on the code whatsoever. They’re simply bits of metadata attached to the Python function parameters and return value. Python dutifully stashes them in a dictionary, assigns the dictionary to the function’s To quote Amahl in Amahl and the Night Visitors, “What’s the use of having it then?” For starters, annotations make good documentation. You can specify the same information in the docstring, of course, but placing it directly in the function definition adds clarity. The types of the arguments and the return value are obvious on sight for a function header like this:
Granted, the interpreter doesn’t enforce adherence to the types specified, but at least they’re clear to someone reading the function definition.
There’s another benefit to using annotations as well. The standardized format in which annotation information is
stored in the When it comes down to it, annotations aren’t anything especially magical. You could even define your own without the special syntax that Python provides. Here’s a Python function definition with type object annotations attached to the parameters and return value: >>>
The following is essentially
the same function, with the >>>
The effect is identical in both cases, but the first is more visually appealing and readable at first glance. In fact, the >>>
Python function annotations are nothing more than dictionaries of metadata. It just happens that you can create them with convenient syntax that’s supported by the interpreter. They’re whatever you choose to make of them. ConclusionAs applications grow larger, it becomes increasingly important to modularize code by breaking it up into smaller functions of manageable size. You now hopefully have all the tools you need to do this. You’ve learned:
Next up in this series are two tutorials that cover searching and pattern matching. You will get an in-depth look at a Python module called re, which contains functionality for searching and matching using a versatile pattern syntax called a regular expression. Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Defining and Calling Python Functions What do you call the information passed to a function?A Parameter is the symbolic name for "data" that goes into a function. There are two ways to pass parameters in C: Pass by Value, Pass by Reference.
What statement allows us to return values from functions?A return statement ends the execution of a function, and returns control to the calling function. Execution resumes in the calling function at the point immediately following the call. A return statement can return a value to the calling function.
What is an argument in coding?An argument is a way for you to provide more information to a function. The function can then use that information as it runs, like a variable. Said differently, when you create a function, you can pass in data in the form of an argument, also called a parameter.
What a function does in a program?A function is simply a “chunk” of code that you can use over and over again, rather than writing it out multiple times. Functions enable programmers to break down or decompose a problem into smaller chunks, each of which performs a particular task.
|