Python Functions

Learning Objectives
Students Will Be Able To: |
---|
Compare Python to JavaScript functions |
Define functions in Python |
Invoke functions in Python |
Use *args and **kwargs parameters |
Road Map
- Setup
- Review the Use Case of Functions - What & Why
- Defining Functions in Python
- A Minimal Function in Python
- Key Differences Between Python & JS Functions
- Calling Functions
- Parameters & Arguments
- Essential Questions
1. Setup
To practice with the code in this lesson:
- Create a new Python-based repl in repl.it
- Name it something like "Python Functions"
Review the Use Case of Functions - What & Why?
Let's review the use case of functions...
❓ What is a function?
A function is a block of code that can be called with inputs and optionally returns an output.
❓ Why are functions necessary in development?
Functions provide:
- Code organization/modularization
- Code reusability
- Readability (when functions are appropriately named)
Functions are the building blocks of programming and all programming languages have them, including Python...
3. Defining Functions in Python
Here's how we define a basic function in Python:

def fahr_to_kevin(temp):
return ((temp - 32) * 5 / 9)) + 273.15
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.
4. A Minimal Function in Python
In JavaScript, we often would "stub up" an "empty" function temporarily:
function someFunction() {
}
The following is how we would "stub up" a function in 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!
5. Key Differences Between Python & JS Functions
Besides the obvious syntactical differences, here are a few other things to be aware of...
Python functions are similar to function declarations in JS (not function expressions)
Functions in Python are defined using the def
keyword.
Unlike JS's function expressions, they cannot be assigned to variables at the time they are being defined:
# This will not work
my_function = def my_function():
pass
However, after being defined, they can be assigned to variables, referenced by dictionaries/lists, etc.
For example, here's how you could dynamically "select" which function to call using a dictionary instead of a potentially huge if...elif...else
statement:
def add(a, b):
return a + b
def subtract(a, b):
return a - b
math_operations = {
'+': add,
'-': subtract
}
selected_operation = '+'
math_operations[selected_operation](2, 4)
> 6
Python has lambda
functions instead of arrow functions
Python lambda
functions are very much like Arrow Functions in JavaScript:
- They implicitly return a single expression's value.
- They are expressions so they are commonly used as "inline" arguments.
- They can be assigned to a variable.
However, unlike arrow functions, they cannot have any code block - just 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 are nifty when using Python functions such as map()
and filter()
- just like how arrow functions are nifty when using array iterator methods.
Python does not "hoist" functions
A key difference between Python and JavaScript functions is that you cannot invoke a Python function before the code that defines it:
# Will cause an error - must call function AFTER it has been defined
add(5, 10)
def add(a, b):
return a + b
6. 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...
7. Parameters & Arguments
Just like in JS, parameters are the placeholders for passing input to a function.
However, Python has more options when defining parameters.
# a & b are parameters
def add(a, b):
return a + b
Also like JS, the values/expressions passed 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 arguments
keyword:
// 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 *
("star") specifier in a parameter list allows us to pass in a varying number of positional arguments into a function:
def fn(*args):
print( type(args) )
for arg in args:
print(arg)
fn(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': []}
# args will be a tuple
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']}
Or, why not use the list()
function to convert the args tuple into a list...
def dev_skills(dev_name, *args):
dev = {'name': dev_name, 'skills': list(args)}
return dev
Python's **
Parameter Specifier (**kwargs
)
First, the reason we name the parameter kwargs
is because it stands for keyword arguments.
A keyword argument is an argument with a name, and this is why keyword arguments are also referred to as named arguments.
For example, assume the following function:
def divide(a, b):
return f'{a} divided by {b} is {a / b}'
Not that it's recommended, but knowing how the function is defined above, we could invoke the function using keyword arguments where the order of the arguments doesn't matter:
divide(b=25, a=100) # returns '100 divided by 25 is 4.0'
However, the above example is not how keyword arguments are commonly used...
First, we use the **
specifier when defining a parameter named **kwargs
(named by convention).
By adding **kwargs
at the end of the parameter list, we can access any number of keyword arguments.
For example:
def dev_skills(dev_name, **kwargs):
# kwargs will be a dictionary!
dev = {'name': dev_name, 'skills': kwargs}
return dev
print(dev_skills('Jackie', HTML=5, CSS=3, JavaScript=4, Python=2))
Combining Required Positional, Optional Positional (*args
) & Keyword (**kwargs
) Arguments
You can use all three types of parameters in the same function, but they have to be defined in the following 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
8. ❓ Essential Questions (2 minutes)
def get_category(points):
if points > 900:
return 'Gold Member'
elif points > 800:
return 'Silver Member'
else:
return 'Bronze Member'
print( get_category(850) )
(1) Which line of code within the above get_category()
function will be the last to execute?
get_category()
function will be the last to execute? return 'Silver Member'
def add(a, b):
return a + b
(2) Assuming the above function:
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)
Answer to (2)
A) No error, because we can add integers and floats together
B) Error, because we cannot "add" an integer to a string
C) Error, because we need to provide two arguments
D) No error, because we can "add" strings together
E) Error, because there are too many arguments
(3) What "feature" in Python would allow the add()
function above to accept any number of numbers to add together?
add()
function above to accept any number of numbers to add together?*args