Key Takeaways
- A function in Python is a reusable block of code that performs a specific task and can optionally accept inputs and return outputs.
- Python functions are first-class objects, which means they can be assigned to variables, passed to other functions, and returned from functions.
- Understanding function parameters in Python, arguments, default values, *args, and **kwargs helps you write flexible and reusable code.
- Every function call creates a separate execution context, and unless specified otherwise, a function returns None by default.
- Knowing how Python passes arguments, handles return values, and manages function scope helps you avoid common programming mistakes.
Introduction
As programs grow, writing the same code repeatedly becomes inefficient and harder to maintain. Functions in Python solve this by allowing you to write reusable blocks of code that perform specific tasks.
You've likely already used built-in functions like print(), len(), and input(). However, understanding what is the function in Python is involves more than calling predefined functions. You also need to learn function syntax in Python, how to define your own functions, pass arguments, use parameters, and return values.
In this guide, you'll learn how to write a function in Python, explore different types of parameters in Python, understand how function calls work, and follow best practices for writing clean, reusable code.
What Is a Function in Python?
A function is a named, reusable block of code that performs a specific task. Instead of writing the same logic multiple times, you define it once and call it whenever needed. This makes programs easier to read, maintain, and debug.
Simply put, what is the function in Python? It is a mechanism for organizing code into smaller, self-contained units that can accept inputs, perform operations, and optionally return a result.
For example, rather than writing the same tax calculation in multiple places, you can create a single function and call it wherever required. If the calculation changes later, you only need to update one location.
Python provides two main categories of functions:
- Built-in functions that come with Python, such as print(), len(), sum(), and type().
- User-defined functions that you create using the def keyword to perform tasks specific to your program.
This combination of Python library functions and custom functions allows developers to build applications efficiently without rewriting common operations.
Why Do Functions Exist?
As programs grow, repeating the same code becomes difficult to manage. Functions solve this by promoting code reuse and modular design.
Functions exist to:
- Eliminate repetitive code
- Break complex problems into smaller tasks
- Improve code readability
- Simplify testing and debugging
- Make programs easier to maintain
For example, an e-commerce application might calculate shipping costs in several places. Instead of duplicating the calculation logic, the application can define one function and call it whenever the shipping cost needs to be calculated.
This approach follows the DRY (Don't Repeat Yourself) principle, a widely accepted software engineering practice that reduces duplication and makes code easier to maintain.
Built-in Functions vs User-Defined Functions
When learning basic functions in Python, it's helpful to distinguish between functions provided by Python and the ones you create yourself.
Built-in Functions
Built-in functions are available immediately after installing Python. They perform common tasks and are part of Python's standard library.
Some commonly used examples include:
| Function | Purpose |
|---|---|
| print() | Displays output on the screen |
| len() | Returns the number of items in an object |
| sum() | Adds all numeric values in an iterable |
| max() | Returns the largest value |
| min() | Returns the smallest value |
| type() | Returns the type of an object |
If you've ever wondered what is built in function in Python, these are ready-made functions that save developers from implementing frequently used operations themselves.
User-Defined Functions
A user-defined function is a function written by the programmer to solve a specific problem. These functions are created using Python's def keyword.
For example, instead of repeatedly calculating the area of a rectangle throughout your program, you can define one reusable function and call it whenever needed.
User-defined functions improve code organization and make applications easier to extend as requirements change.
Examples of Functions in Python
Here are a few simple examples of functions commonly used in Python programming:
| Function | Example Use |
|---|---|
| print() | Display a message |
| len() | Count characters in a string |
| round() | Round a decimal value |
| sorted() | Sort a collection |
| abs() | Return the absolute value of a number |
These examples of functions in Python demonstrate that functions are designed to perform one well-defined task. As you continue learning, you'll create your own functions to automate repetitive operations and build more structured programs.
Understanding Function Definitions
A function definition tells Python what the function does and how it should behave when called. User-defined functions are created using the def keyword.
If you're learning how to write a function in Python, every function definition follows a simple structure.
Function Syntax in Python
def greet(name):
return f"Hello, {name}"
This is the basic function syntax in Python. The function greet() accepts one parameter, performs a task, and returns a value.
How Is a Function Declared in Python?
A function is declared using the def keyword, followed by:
- Function name
- Parentheses ()
- Optional parameters
- Colon (:)
- Indented function body
General syntax:
def function_name(parameters):
# Function body
This is the standard python function definition used throughout Python programs.
Parts of a Python Function Definition
Every function consists of a few important components.
def Keyword
The def keyword tells Python that you're defining a new function.
def greet():
Function Name
The function name identifies the task it performs. Choose descriptive names that make your code easy to understand.
Examples:
calculate_total()
send_email()
find_average()
Parameters
Parameters act as placeholders for values the function expects when it's called.
def greet(name):
Here, name is the parameter.
You'll learn more about python function parameters later in this guide.
Function Body
The function body contains the statements that execute whenever the function is called.
def greet(name):
print(f"Hello, {name}")
Everything inside the indented block belongs to the function.
Return Statement
The return statement sends a result back to the caller.
def square(num):
return num * num
If no return statement is provided, Python automatically returns None.
How to Write a Function in Python
Writing a function usually involves four simple steps:
- Define the function using def.
- Add parameters if input is required.
- Write the logic inside the function.
- Return the result if needed.
Example:
def add(a, b):
return a + b
This function accepts two values and returns their sum.
How Function Calls Work
Defining a function only tells Python what the function should do. The code inside the function runs only when the function is called.
What Happens When You Call a Function?
When Python encounters a function call, it performs these steps:
- Evaluates the arguments.
- Creates a new function frame (execution context).
- Assigns arguments to parameters.
- Executes the function body.
- Returns a value to the caller.
- Removes the function frame after execution.
Example:
def greet(name):
return f"Hello, {name}"
message = greet("Alice")
Here, "Alice" is passed to the parameter name, the function executes, and the returned string is stored in message.
How Python Creates a New Function Frame
Every function call creates its own execution frame, also called a call frame. This frame stores the function's local variables, parameters, and execution state.
Once the function finishes, its frame is removed, and control returns to the line after the function call.
This separation ensures that local variables inside one function don't interfere with variables in another.
How Control Returns After a Function Finishes
A function ends when it:
- Executes a return statement, or
- Reaches the end of its body.
After the function completes, Python returns control to the statement immediately following the function call.
def multiply(a, b):
return a * b
result = multiply(4, 5)
print(result)
In this example, multiply() returns 20, and execution continues with the print() statement.
Why Functions Are Objects in Python
Unlike many programming languages, Python treats functions as first-class objects. This means a function behaves like any other object—you can assign it to a variable, pass it to another function, or even return it from a function.
This flexibility is one of the reasons Python supports powerful programming techniques like callbacks, decorators, and higher-order functions.
Assigning Functions to Variables
Since functions are objects, you can store them in variables without calling them.
def greet():
return "Hello!"
say_hello = greet
print(say_hello())
Here, say_hello refers to the same function object as greet.
Passing Functions as Arguments
A function can also be passed to another function as an argument.
def greet():
return "Hello!"
def display(func):
print(func())
display(greet)
Notice that greet is passed without parentheses because you're passing the function itself, not its return value.
Returning Functions from Functions
Functions can create and return other functions.
def outer():
def inner():
return "Hello!"
return inner
message = outer()
print(message())
This behavior is commonly used in decorators and closures.
Parameters vs Arguments in Python
The terms parameters and arguments are often used interchangeably, but they have different meanings.
A parameter is a variable listed in a function definition, while an argument is the actual value passed when the function is called.
Understanding this difference makes it easier to work with function arguments in Python.
What Are Parameters?
Parameters define the inputs a function expects.
def greet(name):
print(f"Hello, {name}")
Here, name is the parameter.
Parameters act as placeholders until the function is called.
What Is an Argument in Python?
An argument is the value supplied to a function during a function call.
greet("Alice")
Here, "Alice" is the argument passed to the parameter name.
If you've wondered what is an argument in Python, it's simply the value that replaces a parameter when the function executes.
Parameters vs Arguments: Key Differences
| Parameters | Arguments |
|---|---|
| Defined in the function declaration | Passed during the function call |
| Act as placeholders | Provide actual values |
| Exist inside the function definition | Exist when the function is invoked |
Types of Parameters in Python
Python supports different parameter types to make functions flexible and easier to use.
The most common types of parameters in Python are positional, keyword, default, variable-length positional (*args), and variable-length keyword (**kwargs).
Positional Parameters
Positional parameters receive values based on the order in which arguments are passed.
def introduce(name, age):
print(name, age)
introduce("Alice", 25)
The first argument is assigned to name, and the second is assigned to age.
Passing arguments in the wrong order changes the result.
Keyword Parameters
Keyword arguments explicitly specify which parameter should receive each value.
def introduce(name, age):
print(name, age)
introduce(age=25, name="Alice")
Since parameter names are provided, the order doesn't matter.
Keyword arguments also improve readability, especially when a function accepts many parameters.
Default Parameters
A default parameter has a predefined value that Python uses if no argument is supplied.
def greet(name="Guest"):
print(f"Hello, {name}")
greet()
greet("Alice")
Output
Hello, Guest
Hello, Alice
Default parameters reduce the need for multiple function versions while keeping calls simple.
Variable-Length Positional Parameters (*args)
Sometimes you don't know how many positional arguments a function will receive. Prefixing a parameter with * collects all extra positional arguments into a tuple.
def total(*numbers):
return sum(numbers)
print(total(10, 20, 30))
Here, numbers is a tuple containing all the supplied arguments.
Use *args when a function should accept any number of positional values.
Note: args is only a naming convention. The * operator gives it this behavior.
Variable-Length Keyword Parameters (**kwargs)
Prefixing a parameter with ** collects extra keyword arguments into a dictionary.
def student(**details):
print(details)
student(name="Alice", age=20)
Output
{'name': 'Alice', 'age': 20}
**kwargs is useful when a function needs to accept optional named values without knowing them in advance.
Like args, kwargs is only a convention. The ** operator creates the dictionary of keyword arguments.
Using *args and **kwargs Together
A function can use both *args and **kwargs to accept a flexible combination of inputs.
def display(*args, **kwargs):
print(args)
print(kwargs)
display(10, 20, name="Alice", city="Hyderabad")
Output
(10, 20)
{'name': 'Alice', 'city': 'Hyderabad'}
When defining a function, parameters must follow this order:
- Required parameters
- Default parameters
- *args
- **kwargs
Following this order keeps function definitions valid and easy to understand.
How Python Passes Arguments to Functions
When a function is called, Python passes references to objects, not copies of the objects themselves. This means the parameter inside the function refers to the same object as the argument outside the function.
Understanding this behavior helps explain why changes inside a function sometimes affect the original object and sometimes do not.
Python Passes Object References, Not Copies
When you pass an argument to a function, Python creates a new local name that refers to the same object.
def greet(name):
print(name)
student = "Alice"
greet(student)
Here, both student and name refer to the same string object while the function is executing.
Mutation vs Rebinding
A function can either mutate an object or rebind a variable.
Mutation changes the existing object.
Rebinding creates a new reference without changing the original object.
Example of mutation:
def add_item(items):
items.append("Book")
cart = ["Pen"]
add_item(cart)
print(cart)
Output
['Pen', 'Book']
The original list changes because the function modifies the existing object.
Example of rebinding:
def update_name(name):
name = "Bob"
student = "Alice"
update_name(student)
print(student)
Output
Alice
Here, name is rebound to a new string, while student continues to refer to the original object.
Mutable vs Immutable Objects During Function Calls
Whether changes affect the original object depends on whether the object is mutable or immutable.
| Mutable Objects | Immutable Objects |
|---|---|
| List | String |
| Dictionary | Integer |
| Set | Float |
| Bytearray | Tuple |
Mutable objects can be modified after creation, while immutable objects cannot.
Understanding Local Variables and Function Scope
Variables created inside a function belong only to that function. They cannot be accessed outside unless returned.
This limited visibility is known as function scope.
What Are Local Variables?
A local variable is created inside a function and exists only while the function executes.
def calculate():
total = 100
print(total)
Here, total is a local variable.
How Local Names Work
Every function call creates its own namespace for local names.
def greet():
message = "Hello"
print(message)
The variable message exists only inside greet().
Variable Lifetime Inside Functions
Local variables are created when a function starts and are removed when the function finishes.
def square(num):
result = num * num
return result
Once square() returns, result no longer exists.
Return Values in Python
A function can send data back to the caller using the return statement.
The returned value can be stored in a variable, passed to another function, or used in an expression.
What Does the return Statement Do?
The return statement immediately ends the function and sends a value back to the caller.
def add(a, b):
return a + b
Here, the function returns the sum instead of printing it.
Python Function Return Syntax
The basic syntax is:
return expression
The expression can be a value, variable, calculation, or object.
Returning Multiple Values
A function can return multiple values separated by commas.
def calculate(a, b):
return a + b, a - b
sum_value, difference = calculate(8, 3)
Python automatically packs the returned values into a tuple.
Function with Argument and Return Value
A function often accepts arguments, processes them, and returns a result.
def area(length, width):
return length * width
print(area(5, 4))
This is a common example of a function with argument and return value.
Why Functions Return None by Default
If a function doesn't include a return statement, Python automatically returns None.
def greet():
print("Hello")
result = greet()
print(result)
Output
Hello
None
None represents the absence of a return value.
How Many Return Statements Are Allowed in a Function?
A function can contain multiple return statements, but only one executes during a function call.
def check(number):
if number > 0:
return "Positive"
return "Not Positive"
As soon as a return statement executes, the function stops.
Difference Between return and print
Although both are commonly used in functions, they serve different purposes.
| return | |
|---|---|
| Sends a value back to the caller | Displays output on the screen |
| Ends the function immediately | Function continues after printing |
| Returned value can be reused | Printed value cannot be reused directly |
Example:
def square(num):
return num * num
result = square(5)
print(result)
Using return makes a function reusable because the returned value can be stored, combined with other values, or passed to another function. In contrast, print() only displays information and does not make the result available for further computation.
Understanding Side Effects in Functions
A function doesn't always return a value. Sometimes, it changes the program's state or interacts with the outside world. These changes are called side effects.
While side effects are sometimes necessary, they should be used carefully because they can make code harder to understand and test.
What Are Side Effects?
A side effect occurs when a function performs an action other than computing and returning a value.
Common side effects include:
- Modifying a mutable object
- Writing to a file
- Printing output
- Updating a database
- Sending a network request
For example:
def add_item(cart):
cart.append("Book")
Instead of returning a new list, this function modifies the existing one.
Common Examples of Side Effects
Printing to the console:
def greet(name):
print(f"Hello, {name}")
Updating a dictionary:
def update_age(student):
student["age"] = 21
Writing to a file:
def save_message(message):
with open("message.txt", "w") as file:
file.write(message)
Each function changes something outside its local scope.
When Side Effects Are Appropriate
Side effects are useful when interacting with external resources or updating application state. Common use cases include:
- Saving data to a file or database
- Displaying messages to users
- Logging application events
- Sending emails or API requests
For calculations and data processing, prefer returning values instead of modifying external objects. This makes functions easier to test and reuse.
Best Practices for Writing Python Functions
Well-designed functions are easier to understand, maintain, and reuse. Following a few simple practices can improve the quality of your code.
Keep Functions Focused on One Task
A function should perform one specific task.
Instead of combining multiple operations into one function, divide them into smaller functions with clear responsibilities.
Choose Meaningful Function and Parameter Names
Use descriptive names that explain what the function does.
Good examples:
calculate_total()
find_average()
validate_email()
Avoid vague names like:
func()
test()
data()
Meaningful names improve code readability.
Return Values Instead of Printing
Whenever possible, return results instead of printing them.
Good:
def square(num):
return num * num
Less flexible:
def square(num):
print(num * num)
Returned values can be stored, reused, or passed to other functions.
Avoid Mutable Default Arguments
Using mutable objects such as lists or dictionaries as default parameter values can produce unexpected results.
Instead of this:
def add_item(item, items=[]):
items.append(item)
return items
Use:
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items
This creates a new list for each function call.
Keep Parameter Lists Simple
Avoid functions with too many parameters.
If a function requires many inputs, consider grouping related data into a dictionary, object, or data class.
Common Mistakes Beginners Make
Understanding common mistakes can help you write more reliable Python functions.
Confusing Parameters and Arguments
Remember:
- Parameters appear in the function definition.
- Arguments are passed during the function call.
def greet(name): # Parameter
print(name)
greet("Alice") # Argument
Forgetting the return Statement
Without a return statement, a function returns None.
def square(num):
num * num
Correct version:
def square(num):
return num * num
Misunderstanding Mutable Default Arguments
Mutable default values are created only once when the function is defined, not every time it is called.
This can cause unexpected behavior if the object is modified.
Assuming Rebinding Changes the Original Object
Reassigning a parameter inside a function does not modify the original object.
def change_name(name):
name = "Bob"
Here, only the local variable changes.
Mixing Positional and Keyword Arguments Incorrectly
Positional arguments must appear before keyword arguments.
Correct:
introduce("Alice", age=25)
Incorrect:
introduce(age=25, "Alice")
Using print() Instead of return
Printing displays a value, while return sends it back to the caller. Choose return when the result will be used elsewhere in the program.
Summary
Functions are reusable blocks of code that make Python programs more organized, readable, and maintainable. In this guide, you learned how to define and call functions, work with parameters, arguments, default values, *args, and **kwargs, understand function scope and return values, and distinguish return from print(). Mastering these concepts will help you write cleaner, more efficient, and reusable Python code.
Frequently Asked Questions
What is the function in Python?▾
A function is a reusable block of code that performs a specific task. It can accept input through parameters and optionally return a result.
What is an argument in Python?▾
An argument is the actual value passed to a function when it is called.
What are function parameters in Python?▾
Parameters are variables defined in a function that receive values from the caller during execution.
What is a built-in function in Python?▾
A built-in function is a predefined function provided by Python, such as print(), len(), sum(), and type().
What is the difference between parameters and arguments?▾
Parameters are placeholders defined in a function, whereas arguments are the actual values supplied when calling the function.
What is the difference between return and print?▾
return sends a value back to the caller and ends the function. print() simply displays output on the screen without returning the value.
What are *args and **kwargs in Python?▾
*args collects multiple positional arguments into a tuple, while **kwargs collects multiple keyword arguments into a dictionary.
Can a Python function return multiple values?▾
Yes. A function can return multiple values separated by commas. Python packs them into a tuple, which can be unpacked into separate variables.


