Python Language Functions: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
Line 60: Line 60:
m(2) # will display [1, 2] , the state of the list is preserved between the invocation  
m(2) # will display [1, 2] , the state of the list is preserved between the invocation  
     # and is not reset on invocation.
     # and is not reset on invocation.
</syntaxhighlight>
===Gather Positional Arguments with *===
An asterisk (*) indicates that a variable number of positional arguments the function is invoked with are grouped together into a tuple of parameter values:
<syntaxhighlight lang='python'>
def some_func(*args):
  print('tuple:", args)
some_func() # will display "tuple:()"
some_func(1) # will display "tuple:(1)"
some_func(1, 'A') # will display "tuple:(1, 'A')"
</syntaxhighlight>
</syntaxhighlight>



Revision as of 03:34, 20 January 2022

Internal

Overview

A function is a named or unnamed piece of code, which takes any number and type of input parameters and returns any number and type of output results. The function is first defined, then invoked, or called. As pretty much everything else, functions are objects, and they are "first-class citizens", in that they can be assigned to variables, used as arguments, and return them from other functions.

def f():
  pass

print(type(f))

will display:

<class 'function'>

Function Definition

A function is defined by the reserved word def, followed by the function name, parentheses enclosing input parameters, and then finally a colon:

def function_name([parameters]):
  <function body>
def function_name(par1, par2, par3):
  <function body>

Two blank lines are expected after a function definition.

def add(a, b):
  c = a + b
  return c


print(add(1, 2))

Function Name Rules

The function name rules for function names is the same as for variable names.

Function Parameters

A parameter is a variable name used in the function definition. Each parameter translates to a variable private to the function. The parameters are handles for arguments for a particular function invocation. Parameters are optional, a function may have no parameters.

Also see:

Java Methods Parameters and Arguments
Parameters, Variables, Arguments

Default Parameter Values

Default values can be declared for function parameters. The declared default value os used if the caller does not provide the corresponding argument. Naturally, if an argument is provided, it is used instead of the default value.

def make_item(name, color='green', size=1):
    print(f"made {color} {name} in size {size}")

make_item("hat", "red") # will display "made red hat in size 1"

⚠️Default argument values are initialized when the function is [#Function_Definition|defined]], not when it is invoked. The default argument values are part of the function state, which is initialized only once when it is defined. This behavior is exemplified in the following example:

def m(arg, result=[]):
    result.append(arg)
    print(result)

m(1) # will display [1]
m(2) # will display [1, 2] , the state of the list is preserved between the invocation 
     # and is not reset on invocation.

Gather Positional Arguments with *

An asterisk (*) indicates that a variable number of positional arguments the function is invoked with are grouped together into a tuple of parameter values:

def some_func(*args):
  print('tuple:", args)

some_func() # will display "tuple:()"
some_func(1) # will display "tuple:(1)"
some_func(1, 'A') # will display "tuple:(1, 'A')"

Function Body

The body needs to be indented. It includes statements, an optional docstring and an optional return statement.

Docstring

A docstring is a string declared at the beginning of the function body that serves as function documentation. Upon declaration, the string value is assigned to the __doc__ internal variable within the function instance. The string can be a one-line or multi-line and declared between single-quotes, double-quotes or triple quotes. The recommended style is to use triple double-quoted strings as docstrings.

def m(color):
    """
    m() builds a widget of the given color.
    It gets the color and reports what it is going to build.
    I'll do so by:
        1. Reporting the color
        2. Building the widget
    """
    print(f"I will build a {color} widget")

The function's docstring can be printed with the help() function, by passing the function name as argument. The output will be formatted.

help(m)

To print the raw docstring:

print(m.__doc__)

Return Value

The return statement, which is introduced by the return reserved word, ends the function execution and sends back the output result of the function.

def ...
  ...
  return optional_return_value

The compiler will not prevent to declare other statements after the return statement, they be never executed, though. If the function body does not contain a return statement, it will return None.

Style

Exactly 2 blank lines are expected after a function definition. Also see:

Python Style Guide

Function Parameter and Return Value Type Hints

https://docs.python.org/3/library/typing.html#module-typing

The Python runtime does not enforce function and variable type annotations. However, they can be used by third party tools such as type checkers, IDEs, linters, etc. This is a function whose parameter and return has type hints.

def some_func(arg: str) -> str:
  return "hello " + arg

Function Invocation

A function is invoked by prepending parantheses to the name of the function and specifying arguments between parentheses. With no parentheses, Python treats the function like any other object.

Function Arguments

When the function is invoked, we pass an argument for each parameter declared in the function definition. An argument is a value that is passed into the function as function's input. When the function is called with arguments, the values of those argument are copied to their corresponding parameters inside the function. The argument can be another variable, defined in the block that invokes the function. Arguments are passed in parentheses and they are separated by commas. If the function has no parameters, we pass no arguments, but the parentheses still need to be provided.

function_name(arguments)
function_name(arg1, arg2, arg3)

Python is unusually flexible in the manner it handles function arguments. The most common option is to specify the arguments positionally. Another option is to use keyword arguments. Positional and keyword argument can be mixed, but in this case the positional arguments need to come first.

Also see:

Java Methods Parameters and Arguments
Parameters, Variables, Arguments

Positional Arguments

When passing the arguments positionally, they map in order on the declared function parameters. Although very common, a downside of positional arguments is that you need to remember the meaning of each position.

Keyword Arguments

Arguments can be specified by name, even in a different order from their definition in the function:

def menu(appetizer, entree, dessert):
    print(f"Appetizer: {appetizer}, entree: {entree}, dessert: {dessert}")

menu(dessert='cake', appetizer='salad', entree='chicken')

Passing Functions as Arguments

def some_function():
    print('something')

def run_something(f):
    f()

run_something(some_function) # will display "something"

Inner Functions

A function can be defined within other function. Inner functions could be useful when performing some complex tax more than once within another function, to avoid loops and code duplication.

def outer(a, b):
    def inner(c, d):
        return c + d
    return inner(a, b)

print(outer(1, 2))

Closures

An inner function can act as a closure. A closure is a function that is dynamically generated by another function and can both change and remember the values of variables that were created outside itself.

def some_func(arg):
    # we define a closure, which is a function and remembers the argument of the enclosing function
    def closure():
        return f"we remember {arg}"
    return closure

a = some_func("A")  # we create a closure that remembers "A"
b = some_func("B")  # we create a closure that remembers "B"

print(a())  # Will display "we remember A"
print(b())  # Will display "we remember B"

Lambdas

A lambda is an anonymous function expressed a a single statement. It can be used instead of a normal tiny function, by avoiding declaring the function and instead in-lining the behavior.

lambda <arg>: <one-line-statement>

Lambda takes one argument. Does lambda always takes just one argument? Everything between the colon and the terminating parentheses, or other separator in the invoking statement is the definition of the function.

The following example demonstrates the equivalency between a regular function and a lambda:

def regular_function(s):
    return s.capitalize()

def user_of_function(words, f):
    for w in words:
        print(f(w))

data = ['a', 'b', 'c']
user_of_function(data, regular_function)  # this statement uses a regular function
user_of_function(data, lambda w: w.capitalize())  # this statement uses an equivalent lambda, to the same effect

A lambda may call a regular, multi-line function, previously defined. With the above example, the lambda calls the named function instead of implementing the behavior itself:

user_of_function(data, lambda w: regular_function(w))

Built-in Functions

type()

type() returns the type of the argument.

print()

print() If more comma-separated arguments are used, every comma adds a space.

input()

input() instructs Python to pause and read data from stdin. input() returns a string.

s = input('this is the prompt')
print(s)

help()

Display a function's docstring.

Other Functions

max('...'), type conversion functions float(), int(), str()