05 Functions - 01 Defining a Function
Functions are named blocks of code designed to perform a specific task. When you want to execute a task defined in a function, you call the function responsible for it.
Why Use Functions?
- Avoid repetition by defining reusable code blocks which can be called when needed.
- Improve readability and maintainability.
- Allow abstraction by breaking down complex logic into smaller parts.
Function written inside a class becomes a method and is called by either objectname.methodname()
or Classname.methodname()
Functions as First-Class Objects in Python
In Python, functions are first-class objects, meaning they can be treated just like any other object. This includes the ability to:
- Assign functions to variables
- Pass functions as arguments to other functions
- Return functions from other functions
- Store functions in data structures like lists or dictionaries
This characteristic of functions allows for great flexibility and the ability to create more abstract, reusable code.
Defining a Function
To define a function, use the def
keyword, followed by the function name and parameters in parentheses ()
and :
for the defining to begin.
The function body is indented (Whatever gets indented is the functions body).
Defining and Calling a Function
>>> def hello(to):
... print("hello", to)
...
>>> name = input("What's your name? : ")
What's your name? : Sujith
>>> hello(name)
hello Sujith
>>> def greet(username): # Function with a parameter
... """Prints a greeting message."""
... print(f"Hello, {username.title()}!")
...
>>> greet("jess") # Function call with an argument
Hello, Jess!
Function Components:
- Function Name: Identifier for the function.
- Parameters (Arguments): Input values the function can accept.
- Body: Indented block of statements.
- Return Statement: Optionally returns a value.
- Function Call: Executes the function with given arguments.
Function Parameters and Arguments
Functions can accept multiple arguments.
# Function with Multiple Parameters
>>> def add(a, b, c):
... """Returns the sum of three numbers."""
... return a + b + c
...
>>> result = add(2, 3, 5)
>>> print(result)
10
Default Parameter Values
Functions can have default parameter values. If an argument is not provided during the function call, the default value is used.
# Function with Default Argument
>>> def hello(to="world"):
... """Prints a greeting with a default name."""
... print("Hello,", to)
...
>>> hello()
Hello, world
>>> name = input("What's your name? ")
What's your name? : Alice
>>> hello(name)
Hello, Alice
Giving default value to the function like print had sep=' '
and end='\n'
.
If no value is provided default can run, if defined it gets replaced.
Return Values in Python Functions
In Python, functions can return values using the return
statement. This enables functions to produce results that can be stored, manipulated, or used in further calculations. When a function returns a value, it stops executing and hands over the result to the caller.
A returned value can be stored in a variable, used in expressions, or even passed directly into other functions. This makes functions more flexible and powerful in Python programming.
1. Returning a Single Value
You can define a function that performs some operation and returns a single result using the return
statement.
# Function that returns a formatted full name
>>> def format_name(first, last):
... """Returns a formatted full name."""
... full_name = f"{first.title()} {last.title()}"
... return full_name
...
>>> person = format_name("michal", "jackson")
# Call the function and store the returned value in a variable
>>> print(person)
Michael Jackson
2. Returning Multiple Values
Python allows functions to return more than one value. When you return multiple values, Python actually returns them as a tuple. This is useful when you want to return several pieces of data from a single function.
# Function that returns multiple values
>>> def calculate_area_and_perimeter(length, width):
... """Returns both the area and perimeter of a rectangle."""
... area = length * width
... perimeter = 2 * (length + width)
... return area, perimeter # Returning multiple values as a tuple
...
... # Call the function and unpack the returned tuple into separate variables
>>> area, perimeter = calculate_area_and_perimeter(5, 3)
>>> print("Area:", area)
Area: 15
>>> print("Perimeter:", perimeter)
Perimeter: 16
3. Returning No Value (Implicit Return)
A function does not always have to return a value. If a function does not include a return
statement, or if it just has return
without specifying any value, Python will implicitly return None
. This is useful for situations where the function performs an action but doesn’t need to return a result.
# Function that performs an action without returning a value
>>> def print_message(message):
... """Prints the given message but returns nothing."""
... print(message)
...
>>> result = print_message("Hello, World!")
Hello, World!
>>> print(result)
None
4. Returning Values in Expressions
You can also use the return value of a function directly in expressions or as arguments to other functions, making the code more compact and expressive.
# Function returning a value
>>> def add_numbers(a, b):
... """Returns the sum of two numbers."""
... return a + b
...
... # Using the returned value directly in an expression
>>> result = add_numbers(3, 5) * 2
>>> print(result)
16
Assigning Functions to Different Names
A function can be assigned to another name (variable), allowing it to be referenced differently using the variable.
# Assigning a function to a new name
def f(a, b, c):
...
g = f # g is now another name for f
>>> def greet(name):
... return f"Hello, {name}!"
...
... # Assigning the function to a variable
>>> greeting_function = greet
>>> # Calling the function using the variable
>>> print(greeting_function("Alice"))
Hello, Alice!
Passing Functions as Arguments
Since functions are objects, you can pass them as arguments to other functions, which allows for higher-order functions (functions that take other functions as arguments).
This technique is useful for passing functions as arguments to other functions.
# Applying a function repeatedly
>>> def apply(func, x, n):
... res = x
... for i in range(n):
... res = func(res)
... return res
...
>>> def square(x):
... return x * x
...
>>> print(apply(square, 5, 2))
625
Here, square
is passed as func
to apply()
.
Returning Functions from Functions
Function definitions can be conditionally assigned.
if condition:
def f(a, b, c):
...
else:
def f(a, b, c):
...
Functions can also be returned from other functions. This is useful for scenarios where the returned function is created dynamically or customized based on input.
>>> def multiplier(factor):
... """Returns a function that multiplies its argument by a given factor."""
... def multiply(x):
... return x * factor
... return multiply
...
... # Create a function that multiplies by 3
>>> times_three = multiplier(3)
>>> print(times_three(5))
15
- The
multiplier()
function returns a new functionmultiply()
that multiplies its argument by a specific factor. - We create a function
times_three
by callingmultiplier(3)
, and then use it to multiply5
by3
, resulting in15
.
Customizing Function Behavior
Functions can be customized based on parameters, such as sorting based on a comparison function.
>>> def sort_function(l, cmp_fn=default_cmp_fn):
... pass