Skip to main content

Functions

Functions are named blocks of code, designed to do one specific job.

Information passed to a function is called an argument, and information received by a function is called a parameter.

A simple function

def greet_user():
"""Display a simple greeting."""
print('Hello!')

greet_user()

Passing an argument

def greet_user(username):
print('Hello, ' + username)

greet_user('dude')

Default values for parameters

When function calls omit this argument the default value will be used. Parameters with default values must be listed after parameters without default values in the function's definition so positional arguments can still work correctly.

We can use None to make an argument optional

def make_pizza(topping='bacon'):
print('Have a ' + topping + ' pizza!')

make_pizza()
make_pizza('pepperoni')

Returning a value

def add_numbers(x, y):
return x + y

sum = add_numbers(3, 5)
print(sum)

Parameters passing

  • positional-or-keyword
  • positional-only
  • keyword-only
  • var-positional
  • var-keyword

Positional and Keyword Arguments

When we use positional arguments Python matches the first argument in the funtion call with the first parameter in the function definition, and so forth.

sum = add_numbers(3,5)

With keyword arguments, we specify which parameter each argument should be assigned to in the function call. When we use keyword arguments, the order of the arguments doesn't matter.

sum = add_numbers(x=3, y=5)
sum = add_numbers(y=5, x=3)

Passing an arbitrary number of arguments

Sometimes we won't know how many arguments a function will need to accept. Python allows us to collect an arbitrary number of arguments into one parameter using the * operator. A parameter that accepts an arbitrary number of arguments must come last in the function definition.

The ** operator allows a parameter to collect an arbitrary number of keyword arguments

# use arbitrary number of positional arguments using *
def create_pizza(item_number, *toppings):
pizza = {'Pizza number' : item_number}

for topping in toppings:
pizza[topping] = 1

return pizza

print (create_pizza(1, 'onion', 'tomato'))
print (create_pizza(2, 'mushroom'))

# use arbitrary number of keyword arguments using **
def create_pizza(item_number, **toppings):
pizza = {'Pizza number' : item_number}

for key, value in toppings.items():
pizza[key] = value

return pizza

print (create_pizza(1, topping1='onion', topping2='tomato'))
print (create_pizza(2, topping='mushroom'))

# another instance of *
def print_args(d1, d2, d3):
print(d1, d2, d3)

data = ('foo', 'bar', 'baz')

print_args(data)
TypeError: missing positional arguments d2 and d3

print_args(*data)
foo bar baz

kwargs (keyword arguments, changes the passed keyword arguments into a dictionary)

def print_kwargs(**kwargs):
print(kwargs)

print_kwargs(foo='bar', hello='world')
{'foo': 'bar', 'hello': 'world'}

Nested Functions

Because of the first class nature of python, we can define functions inside other functions.