Introduction to Python Functions, Parameters, Return Values; Define and Call Python Functions

Beatme CodeBY-NC-ND
14:36 read·1899 words· published

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 and docstring 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.

functions.py
# 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'.

functions.py
# 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.

functions.py
# 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.

functions.py
# 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.

functions.py
# 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.

functions.py
# 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

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 the def 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 the return (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.

functions.py
# A simple function
def simple(a: int = 1) -> None:
	'''A simple function~~~!

Sure enough, it's easy.
'''

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.

functions.py
# 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.

functions.py
# Define an anonymous functions
div = lambda a, b: a / b

print(div(9, 3))
3.0

Source Code

functions.py·codebeatme/python·GitHub