Introduction to Python Functions, Parameters, Return Values; Define and Call Python Functions
Define Python Functions
Typically, Python functions are defined in modules and serve as targets that can be called externally, and are written in the following basic format.
def <funcname>(<parameterlist>)
<docstring>
<block>
- funcname part
funcname
is the name of the function, which needs to conform to Python's identifier specification, and cannot use Python keywords or reserved keywords.- parameterlist part
parameterlist
is the parameter list of a function, which defines all the parameters of the function, separated by,
.- docstring part
docstring
is the documentation string for the function and contains a description of the function, this is not mandatory, a function can have no documentation string.- block part
block
is the body code of the function, and both it anddocstring
need to be indented with some kind of whitespace character to indicate that they belong to the function.
Here’s a simple Python function, hello
, with one parameter named name
.
# Define a function hello with the parameter name
def hello(name):
'''A super simple function'''
print(f'Hello, {name}')
Call Python Functions
Calling functions is an easy task in any language, and this is true for Python as well; here is the basic format for calling functions.
<funcname>(<argumentlist>)
- funcname part
funcname
is the name of the function to be called.- argumentlist part
argumentlist
is the list of arguments passed to the function.
In the following code, we call the function hello
and pass the argument 'Kitty'
.
# Call the function hello
hello('Kitty')
Hello, Kitty
Python Code Indentation
Python illustrates code hierarchy through indentation, which is generally accomplished by using spaces or tabs. Code with the same number of spaces or tabs, counting from the beginning of the line, is considered to be at the same level.
Don't mix spaces and tabs for indentation in Python
Although, in a Python script file, it is permissible to use a mix of spaces and tabs for indentation, for example, using two spaces for one level and three tabs for another. However, this is not desirable behavior, as it can lead to unnecessary errors or make the code less readable.
Parameters of Python Functions
Python functions can have default values for their parameters, which can be set with =
when defined. The default value is calculated only once, so the default value of the parameter points to the same object. If the default value is a list, the list may contain different elements each time the function is called.
How do I restrict the parameters of a Python function to positional parameters?
Add the special symbol /
to Python functions; parameters before this symbol can only be used as positional parameters.
How do I restrict the parameters of a Python function to keyword parameters?
Adding a variadic parameter marked with *
to a Python function (which can retain only *
itself), then the parameters after that parameter can only be used as keyword (named) parameters. The parameter marked with *
can only appear after the symbol /
in a function, otherwise positional parameters will not be identified.
The following function, add
, has default values for its parameters x
, y
, and they can only be used as positional parameters, and the parameter z
can only be used as a keyword parameter. When parameter y
is used with its default value, the number of elements in the list increases with the number of calls.
# Define the addition function
def add(x=1, y=[], /, *, z):
# Add the number 100 to the list y
y.append(100)
print(y)
# Calculate the sum of the numbers contained in x, y, and z
num = 0
for i in y:
num += i
return x + num + z
# z can only be used as a keyword parameter
print(add(z=1))
# x is used as a positional parameter
print(add(1, z=3))
[100]
102
[100, 100]
204
Variadic Parameters of Python Functions
When you add *
or **
in front of a Python function’s parameter, the parameter becomes a variadic parameter. The parameter marked with the symbol *
is a tuple that contains all the positional parameters that are not in the parameter list at the time the function is called. The parameter marked with the symbol **
is a dictionary, which should be located at the end of the parameter list, and contains all the keyword parameters that are not in the parameter list when the function is called. The key of the dictionary key-value pair is a string that represents the name of the parameter, and the value of the key-value pair is the corresponding value of the parameter.
If both *
and **
are used in the parameter list, the *
needs to have the parameter name after it.
How to pass values from lists, tuples, ranges, dictionaries for Python functions?
If the values prepared for function parameters are stored in Python sequence or mapping objects, the passing of the parameters can be simplified by unpacking them. This is done by unpacking sequence objects (including lists, tuples, and ranges) with *
and mapping objects (mainly dictionaries) with **
.
The following function, mlp
, has variadic parameters nums
, info
. When called, we pass multiple numbers for mlp
to multiply.
# Define the multiplication function
def mlp(*nums, **info):
# Show keyword parameters
print(info)
# Calculate the positional parameters contained in nums
num = 1
for i in nums:
num *= i
return num
# Pass multiple numbers for multiplication
print(mlp(2, 3, 4, 5, tip='Here is a little hint'))
{'tip': 'Here is a little hint'}
120
Return Values of Python Functions
With the return
statement, you can return a specified value for a Python function; if return
is not used or return
does not give a return value, the function returns None
by default.
Signatures of Python Functions
By default, the signature of a Python function contains only the name of the function, which means that a function defined later in the same namespace overrides a function of the same name defined earlier, regardless of its parameters and return value.
In the following code, the second defined function wait
will override the first defined wait
, so the final statement wait(3)
calls the second wait
function.
# This function will be overridden by the wait function defined later
def wait(seconds):
print(f'Wait {seconds} second(s)')
# The first defined wait function is called
wait(3)
# This function overrides the previously defined wait function
def wait(hours, minutes=5):
print(f'Wait {hours} hour(s) {minutes} minute(s)')
# The last defined wait function is called
wait(3)
Wait 3 second(s)
Wait 3 hour(s) 5 minute(s)
Namespaces of Python Functions
Yes, Python functions have their own namespace, so variables you define inside a function can have the same name as variables outside the function, and they will be treated differently.
Python functions cannot directly assign or modify variables defined outside the function
According to the general principle of scope, you can access a variable defined outside of a function within the function, but only to read it; when you try to write to an external variable, it doesn’t work as expected because Python will assume that the assignment statement is the definition of a new variable.
To implement the modification of external variables within a function, you need to use the global
or nonlocal
keywords.
The following function show
does not modify the message
variable defined in the module, but defines its own message
.
# Define the variable message in the module
message = 'I am a module variable'
# The show function defines its own message
def show():
# This does not modify the message defined by the module
message = 'I am a variable in the function'
print(message)
# The show_again function uses the message variable defined by the module
def show_again():
print(message)
show()
show_again()
I am a variable in the function
I am a module variable
Python Nested Functions
A nested function is a function defined in another function or method that uses a syntax that is no different from that of a normal function, and the accessibility of the defined nested function is generally equivalent to that of a variable in the same namespace.
Of course, you can make nested functions callable in more places, by returning values or otherwise, but this defeats the purpose of defining nested functions.
The function check
is a nested function defined in the function add_list
to exclude numbers greater than 10
from the tuple.
# Sums all numbers less than or equal to 10 in a tuple
def add_list(*l):
# Nested function check, checks a number, returns 0 if greater than 10
def check(i):
return 0 if i > 10 else i
# Call check to ignore numbers greater than 10 in a tuple
num = 0
for i in l:
num += check(i)
return num
print(add_list(4, 2, 11, 3))
9
Python Lambda Expressions
Using lambda expressions, you can easily define an anonymous function. Unlike normal functions, functions defined by lambda expressions do not support documentation strings and annotations of parameters or return values, and allow only a single expression whose result is the function’s return value, without the need for a return
statement.
In the following code, we define an anonymous function that does division using a lambda expression.
# Define an anonymous functions
div = lambda a, b: a / b
print(div(9, 3))
3.0
Comments of Python Functions
Writing documentation strings for Python functions makes it easy for developers to understand how to use the functions, but of course this requires that the development tools have the appropriate code hints.
A documentation string is essentially a string literal written in a function, which must be the first line of code in the body of the function, and may be concatenated in close proximity or with whitespaces, e.g.,
'This is a very useful '"function"
, but it should not contain content or operations that need to be calculated, e.g.,'This is a very useful '+"function"
,f'It can compute {count} targets'
.When using triple quotes, the documentation string can be multi-line, and any whitespace characters in the string are preserved, but this is only reflected in the
__doc__
variable of the function object, and the development tool should handle whitespace characters to present a more user-friendly information to the developer.How do I annotate the parameters and return values of Python functions?
Unlike function documentation strings, annotations are mainly used to specify the types of function parameters and return values, and multiple types can be separated by
|
. Parameter annotations can be done by writing:
after the parameter name, followed by the type of the parameter, e.g.,name:str
. Return values are annotated by writing->
before the:
at the end of thedef
statement, followed by the type of the return value, e.g.def hi()->str|None
.All annotations are stored as a dictionary in the
__annotations__
variable of the function object, the key of the dictionary key-value pair is a string contains thereturn
(representing the return value) or the parameter name, and the value of the key-value pair is a type object representing the type of the return value or parameter.