Intro to Python Functions
Learning Objectives
Students Will Be Able To: |
---|
Contrast Python and JavaScript functions |
Define functions in Python |
Invoke functions in Python |
Use *args and **kwargs parameters |
Set Up
To experiment with the code in this lesson, please use a Python-based repl in repl.it
Review the Use Case of Functions - What & Why?
What is a function?
A function is a block of statements that can be called with inputs and often return an output.
Why are there functions?
Functions provide:
Functions are the building blocks of programming and all programming languages have them, including Python...
Defining Functions in Python
Here's how we define a basic function in Python:
As you can see:
- The first line starts with the
def
keyword. This defines a function. - The next word is the name (identifier) of the function.
- Following that is a parameter list inside parentheses.
- The first line ends with a colon.
- The first line is followed by an indented code block that we have become familiar with.
- Python functions, like JS, optionally return a value using a
return
statement.
A Minimal Function in Python
In JavaScript, we often would create an "empty" function temporarily.
In a Python repl, let's "stub up" a function Python:
def first_function():
pass
The pass
statement is simply a "do nothing" statement and is useful here to create a function that has at least one statement in its block, which is a requirement.
What does a JS function return by default if it doesn't include a return statement?
undefined
Let's see what a Python function returns by default:
def first_function():
pass
# Assign value returned by default
result = first_function()
print(result)
Good guess!
Key Differences Between Python & JS Functions
Besides the obvious syntactical differences, here are a few other things to be aware of
Python has a different sort of anonymous/inline function
Python function declarations are defined using the def
keyword and these functions are never assigned to variables as in JavaScript.
However, Python does have a the concept of anonymous and/or inline functions - called lambda
functions.
lambda
functions are very much like Arrow Functions in JavaScript:
- They implicitly return a single expression's result.
- They can be assigned to a variable.
However, they cannot have any code block - only a single expression that has its result implicitly returned.
For example:
// JavaScript
const nums = [1, 3, 2, 6, 5]
let odds = nums.filter((num) => num % 2)
# Python
nums = [1, 3, 2, 6, 5]
odds = list( filter(lambda num: num % 2, nums) )
Lambda functions in Django are really nifty when using Python functions such as map()
.
Python does not "hoist" functions
The last key difference between Python and JavaScript functions is that you cannot invoke a Python function before the code that defines it:
# Not allowed until after the code below
add(5, 10)
def add(a, b):
return a + b
Calling Functions
In Python, calling functions is the same as it is in JavaScript:
def add(a, b):
return a + b
def sub(a, b):
return a - b
def compute(a, b, op):
return op(a, b)
print( compute(1, 2, add) )
Yup, functions in Python can be passed to other functions - callbacks exist in Python!
Let's learn more about Python's parameters & arguments...
Parameters & Arguments
Just like in JS, parameters are the placeholders for passing input to a function.
# a & b are parameters
def add(a, b):
return a + b
Also like JS, the values/expressions passed in to a function when calling it are known as arguments:
num = 5
# num & 10 are arguments
add(num, 10)
However, unlike JavaScript, Python requires that the correct number of arguments be provided when calling a function. For example:
def add(a, b):
return a + b
add()
# Generates the following error:
# TypeError: add() missing 2 required positional arguments: 'a' and 'b'
Accepting a varying number of arguments
In JavaScript, we were able to access "extra" arguments being passed in to a function by using the special arguments
:
// Using the arguments special variable
function sum() {
let total = 0
for (arg of arguments) total += arg
return total
}
console.log(sum(1, 5, 10)) // -> 16
Or preferably by using ES2015's rest parameters:
function sum(...nums) {
return nums.reduce((sum, num) => sum + num, 0)
}
console.log(sum(1, 5, 10)) // -> 16
Python's *
Parameter Specifier (*args
)
Using the *
specifier in a parameter list allows us to pass in a varying number of arguments into a function:
def f(*args):
print( type(args) )
for arg in args:
print(arg)
f(1, 2, 'SEI')
Output:
<class 'tuple'>
1
2
SEI
The identifier used with *
, i.e., args
, can be anything, however by convention use args
.
Always use the *args
parameter after any required positional parameters. For example:
def dev_skills(dev_name, *args):
dev = {'name': dev_name, 'skills': []}
for skill in args:
dev['skills'].append(skill)
return dev
print(dev_skills('Alex', 'HTML', 'CSS', 'JavaScript', 'Python'))
# -> {'name': 'Alex', 'skills': ['HTML', 'CSS', 'JavaScript', 'Python']}
Python's **
Parameter Specifier (**kwargs
)
If you'd like to be able to access a varying number of named arguments, use **kwargs
at the end of the parameter list:
def dev_skills(dev_name, **kwargs):
dev = {'name': dev_name, 'skills': {}}
# unpacking the tuples returned by the items function
for skill, rating in kwargs.items():
dev['skills'][skill] = rating
return dev
print(dev_skills('Jackie', HTML=5, CSS=3, JavaScript=4, Python=2))
Combining Positional, *args
& **kwargs
You can define all three types of parameters in a function, but you have to do it in this order:
def arg_demo(pos1, pos2, *args, **kwargs):
print(f'Positional params: {pos1}, {pos2}')
print('*args:')
for arg in args:
print(' ', arg)
print('**kwargs:')
for keyword, value in kwargs.items():
print(f' {keyword}: {value}')
arg_demo('A', 'B', 1, 2, 3, color='purple', shape='circle')
Output:
Positional params: A, B
*args:
1
2
3
**kwargs:
color: purple
shape: circle
Review Questions
Take a moment to review the following questions:
❓ Assuming the following function:
def add(a, b):
return a + b
Which of the following statements will result in an error?
(there could be more than one)
A) add(10, 100.)
B) add(10, '10')
C) add(100)
D) add('abc', 'def')
E) add(10, 20, 30)
❓ What "feature" in Python would allow the add
function above to accept any number of numbers to add together?