Defining functions
This chapter will discuss how to define your own functions, pass arguments to them and get back results. You'll also learn more about the print()
built-in function.
def
Use the def
keyword to define a function. The function name is specified after the keyword, followed by arguments inside parentheses and finally a :
character to end the definition. It is a common mistake for beginners to miss the :
character. Arguments are optional, as shown in the below program.
# no_args.py
def greeting():
print('-----------------------------')
print(' Hello World ')
print('-----------------------------')
greeting()
The above code defines a function named greeting
and contains three statements as part of the function. Unlike many other programming languages, whitespaces are significant in Python. Instead of a pair of curly braces, indentation is used to distinguish the body of the function and statements outside of that function. Typically, 4 spaces is used, as shown above. The function call greeting()
has the same indentation level as the function definition, so it is not part of the function. For readability, an empty line is used to separate the function definition and subsequent statements.
$ python3.9 no_args.py
-----------------------------
Hello World
-----------------------------
Functions have to be declared before they can be called. As an exercise, call the function before declaration and see what happens for the above program.
As per PEP 8: Style Guide for Python Code, it is recommended to use two blank lines around top level functions. However, I prefer to use a single blank line. For large projects, specialized tools like pylint and black are used to analyze and enforce coding styles/guidelines.
To create a placeholder function, you can use the
pass
statement to indicate no operation. See docs.python: pass statement for details.
Accepting arguments
Functions can accept one or more arguments, specified as comma separated variable names.
# with_args.py
def greeting(ip):
op_length = 10 + len(ip)
styled_line = '-' * op_length
print(styled_line)
print(f'{ip:^{op_length}}')
print(styled_line)
greeting('hi')
weather = 'Today would be a nice, sunny day'
greeting(weather)
In this script, the function from the previous example has been modified to accept an input string as the sole argument. The len() built-in function is used here to get the length of a string value. The code also showcases the usefulness of variables, string operators and string formatting.
$ python3.9 with_args.py
------------
hi
------------
------------------------------------------
Today would be a nice, sunny day
------------------------------------------
As an exercise, modify the above program as suggested below and observe the results you get.
- add print statements for
ip
,op_length
andstyled_line
variables at the end of the program (after the function calls) - pass a numeric value to the
greeting()
function - don't pass any argument while calling the
greeting()
function
The argument variables, and those that are defined within the body, are local to the function and would result in an exception if used outside the function. See also docs.python: Scopes and Namespaces and docs.python: global statement.
Python being a dynamically typed language, it is up to you to sanitize input for correctness. See also docs.python: Support for type hints and realpython: Python Type Checking Guide.
Default valued arguments
A default value can be specified during the function definition. Such arguments can be skipped during the function call, in which case they'll use the default value. They are also known as keyword arguments. Here's an example:
# default_args.py
def greeting(ip, style='-', spacing=10):
op_length = spacing + len(ip)
styled_line = style * op_length
print(styled_line)
print(f'{ip:^{op_length}}')
print(styled_line)
greeting('hi')
greeting('bye', spacing=5)
greeting('hello', style='=')
greeting('good day', ':', 2)
There are various ways in which you can call functions with default values. If you specify the argument name, they can be passed in any order. But, if you pass values positionally, the order has to be same as the declaration.
$ python3.9 default_args.py
------------
hi
------------
--------
bye
--------
===============
hello
===============
::::::::::
good day
::::::::::
As an exercise, modify the above script for the below requirements.
- make the spacing work for multicharacter
style
argument - accept another argument with a default value of single space character that determines the character to be used around the centered
ip
value
As another exercise, what do you think will happen if you use greeting(spacing=5, ip='Oh!')
to call the function shown above?
Arguments declared without default values can still be used as keyword arguments during function call. This is the default behavior. Python provides special constructs
/
and*
for stricter separation of positional and keyword arguments. See docs.python: Special parameters for details.
Return value
The default return value of a function is None
, which is typically used to indicate the absence of a meaningful value. The print()
function, for example, has a None
return value. Functions like int()
, len()
and type()
have specific return values, as seen in prior examples.
>>> print('hi')
hi
>>> value = print('hi')
hi
>>> value
>>> print(value)
None
>>> type(value)
<class 'NoneType'>
Use the return
statement to explicitly give back a value when the function is called. You can use this keyword by itself as well (default value is None
).
>>> def num_square(n):
... return n * n
...
>>> num_square(5)
25
>>> num_square(3.14)
9.8596
>>> op = num_square(-42)
>>> type(op)
<class 'int'>
On encountering a
return
statement, the function will be terminated and further statements, if any, present as part of the function body will not be executed.
A common beginner confusion is mixing up the
print()
function and thereturn
statement. See stackoverflow: What is the formal difference between “print” and “return”? for examples and explanations.
A closer look at the print() function
The help
documentation for the print()
function is shown below.
As you can see, there are four default valued arguments. But, what does value, ...,
mean? It indicates that the print()
function can accept arbitrary number of arguments. Here's some examples:
# newline character is appended even if no arguments are passed
>>> print()
>>> print('hi')
hi
>>> print('hi', 5)
hi 5
>>> word1 = 'loaf'
>>> word2 = 'egg'
>>> print(word1, word2, 'apple roast nut')
loaf egg apple roast nut
If you observe closely, you'll notice that a space character is inserted between the arguments. That separator can be changed by using the sep
argument.
>>> print('hi', 5, sep='')
hi5
>>> print('hi', 5, sep=':')
hi:5
>>> print('best', 'years', sep='.\n')
best.
years
Similarly, you can change the string that gets appended to something else.
>>> print('hi', end='----\n')
hi----
>>> print('hi', 'bye', sep='-', end='\n======\n')
hi-bye
======
The
file
argument will be discussed later. Writing your own function to accept arbitrary number of arguments will also be discussed later.
Docstrings
Triple quoted strings are also used for multiline comments and to document various part of a Python script. The latter is achieved by adding help content as string literals (but without being assigned to a variable) at the start of a function, class, etc. Such literals are known as documentation strings, or docstrings for short. Idiomatically, triple quoted strings are used for docstrings. The help()
function reads these docstrings to display the documentation. There are also numerous third-party tools that make use of docstrings.
Here's an example:
>>> def num_square(n):
... """
... Returns the square of a number.
... """
... return n * n
...
>>> help(num_square)
Calling help(num_square)
will give you the documentation as shown below.
num_square(n)
Returns the square of a number.
See docs.python: Documentation Strings for usage guidelines and other details.