Functions are one of the most important concepts in Python programming.
When you start writing Python programs, you may initially write all your code in one place. But as your application becomes larger, the code can become difficult to read, maintain, and reuse.
Python functions solve this problem.
A function allows you to group related instructions into a reusable block of code. Instead of writing the same logic multiple times, you can define it once and call it whenever you need it.
For example:
def greet():
print("Hello, Python!")
greet()
Output:
Hello, Python!
In this complete beginner-friendly guide, you will learn:
- What a Python function is
- How to define a function
- How to call a function
- Function parameters
- Function arguments
- Return values
- Default arguments
- Keyword arguments
*args**kwargs- Local and global variables
- Lambda functions
- Recursive functions
- Type hints
- Docstrings
- Nested functions
- Higher-order functions
- Common mistakes
- Best practices
- Practical examples
What Is a Function in Python?
A function is a reusable block of code designed to perform a particular task.
Instead of writing:
print("Welcome to our website")
print("Welcome to our website")
print("Welcome to our website")
you can create a function:
def welcome():
print("Welcome to our website")
Then call it whenever you need it:
welcome()
welcome()
welcome()
The main idea is simple:
Write the logic once and reuse it whenever required.
Functions make programs more:
- Organized
- Readable
- Reusable
- Maintainable
- Testable
Why Are Functions Important?
Imagine you are creating a shopping application.
You may need separate operations for:
- Calculating product prices
- Calculating discounts
- Calculating taxes
- Sending emails
- Validating users
- Processing payments
Without functions, all of these operations could end up mixed together.
With functions, you can separate them:
def calculate_price():
pass
def calculate_discount():
pass
def calculate_tax():
pass
def send_email():
pass
Each function handles one responsibility.
This makes your application easier to understand and maintain.
Python Function Syntax
The basic syntax for defining a function is:
def function_name():
# function body
The def keyword tells Python that you are defining a function.
For example:
def say_hello():
print("Hello!")
Here:
def→ defines the functionsay_hello→ function name()→ parameter list:→ starts the function body- Indented code → function body
How to Call a Function
Defining a function does not automatically execute it.
You need to call the function.
Example:
def say_hello():
print("Hello!")
say_hello()
Output:
Hello!
The function runs when Python reaches:
say_hello()
Creating a Simple Python Function
Let’s create a function that displays a message:
def welcome():
print("Welcome to Python programming!")
Now call it:
welcome()
Output:
Welcome to Python programming!
You can call the same function multiple times:
welcome()
welcome()
welcome()
Output:
Welcome to Python programming!
Welcome to Python programming!
Welcome to Python programming!
This demonstrates the reusability of functions.
Functions with Parameters
A function can receive information through parameters.
For example:
def greet(name):
print("Hello", name)
Call the function:
greet("Ankit")
Output:
Hello Ankit
Here:
name
is a parameter.
When you call:
greet("Ankit")
"Ankit" is an argument.
Parameters vs Arguments
Beginners often confuse these two terms.
Parameter
A parameter is the variable defined inside the function declaration.
def greet(name):
print(name)
Here name is a parameter.
Argument
An argument is the actual value passed to the function.
greet("Ankit")
Here "Ankit" is an argument.
A simple way to remember:
Parameter = placeholder
Argument = actual value
Multiple Parameters
A function can accept multiple parameters.
def add_numbers(a, b):
result = a + b
print(result)
Call it:
add_numbers(10, 20)
Output:
30
Another example:
def introduce(name, age):
print("Name:", name)
print("Age:", age)
Call:
introduce("Ankit", 25)
Returning a Value from a Function
A function can return a result using the return statement.
Example:
def add(a, b):
return a + b
Now:
result = add(10, 20)
print(result)
Output:
30
The function calculates the value and returns it to the caller.
return vs print
These are not the same.
Using print
def add(a, b):
print(a + b)
This displays the result.
Using return
def add(a, b):
return a + b
This sends the result back to the caller.
For reusable programming logic, return is often more useful.
For example:
def add(a, b):
return a + b
result = add(10, 20)
final_result = result * 2
print(final_result)
Output:
60
Because the function returned a value, the result can be used elsewhere.
A Function Can Return Multiple Values
Python allows a function to return multiple values.
Example:
def calculate(a, b):
return a + b, a - b
You can store the results:
addition, subtraction = calculate(10, 5)
print(addition)
print(subtraction)
Output:
15
5
Technically, Python returns these values as a tuple.
Returning Nothing
If a function does not explicitly return a value, Python returns None.
Example:
def hello():
print("Hello")
If you write:
result = hello()
print(result)
Output:
Hello
None
Default Parameters
Python functions can have default values.
Example:
def greet(name="Guest"):
print("Hello", name)
Calling:
greet()
produces:
Hello Guest
Calling:
greet("Ankit")
produces:
Hello Ankit
Default parameters are useful when a value is optional.
Multiple Default Parameters
You can have multiple default values:
def create_user(name="Guest", age=18):
print(name, age)
You can call:
create_user()
or:
create_user("Ankit")
or:
create_user("Ankit", 25)
Keyword Arguments
Python allows you to pass arguments using parameter names.
Example:
def introduce(name, age):
print(name)
print(age)
Instead of:
introduce("Ankit", 25)
you can write:
introduce(name="Ankit", age=25)
This is called a keyword argument.
Positional Arguments
When you pass arguments based on their position, they are called positional arguments.
Example:
def student(name, age):
print(name, age)
student("Ankit", 25)
Here:
"Ankit"goes toname25goes toage
The order matters.
Positional and Keyword Arguments Together
You can combine them:
def student(name, age, city):
print(name, age, city)
student("Ankit", age=25, city="Jaipur")
A positional argument generally comes before keyword arguments.
*args in Python
Sometimes you don’t know how many positional arguments a function will receive.
Python provides *args.
Example:
def add_numbers(*numbers):
total = 0
for number in numbers:
total += number
return total
Now you can pass any number of values:
print(add_numbers(10, 20))
print(add_numbers(10, 20, 30))
print(add_numbers(10, 20, 30, 40))
Output:
30
60
100
Inside the function, numbers is a tuple containing the positional arguments.
**kwargs in Python
**kwargs allows a function to accept an arbitrary number of keyword arguments.
Example:
def user_info(**details):
print(details)
Call:
user_info(name="Ankit", age=25, city="Jaipur")
Output will be a dictionary-like representation:
{'name': 'Ankit', 'age': 25, 'city': 'Jaipur'}
Inside the function, details is a dictionary.
*args vs **kwargs
| Feature | *args | **kwargs |
|---|---|---|
| Handles | Positional arguments | Keyword arguments |
| Internal type | Tuple | Dictionary |
| Syntax | *args | **kwargs |
| Example | func(10, 20) | func(name="Ankit") |
Example:
def example(*args, **kwargs):
print(args)
print(kwargs)
Call:
example(10, 20, name="Ankit", age=25)
Keyword-Only Parameters
Python also allows you to require certain parameters to be passed by name.
Example:
def create_user(name, *, age, city):
print(name, age, city)
This works:
create_user("Ankit", age=25, city="Jaipur")
But the following is not valid:
create_user("Ankit", 25, "Jaipur")
The * makes age and city keyword-only parameters.
Positional-Only Parameters
Python also supports positional-only parameters using /.
Example:
def calculate(a, b, /):
return a + b
You must provide these parameters positionally:
calculate(10, 20)
Using:
calculate(a=10, b=20)
is not allowed for those positional-only parameters.
Local Variables
Variables created inside a function are generally local to that function.
Example:
def calculate():
price = 100
print(price)
calculate()
The variable price belongs to the function’s local scope.
Trying to use it outside:
print(price)
will result in a NameError because price is not defined in the global scope.
Global Variables
A variable defined outside functions is generally in the global scope.
Example:
name = "Ankit"
def greet():
print(name)
greet()
The function can read the global variable.
However, relying heavily on global variables can make programs harder to maintain.
The global Keyword
Python provides the global keyword when you need to rebind a global variable from inside a function.
Example:
count = 0
def increase():
global count
count += 1
increase()
print(count)
Output:
1
However, using global state excessively is generally discouraged.
Returning values or passing data through parameters is often cleaner.
Function Scope
Python follows rules for finding variables called LEGB:
- Local
- Enclosing
- Global
- Built-in
For example:
name = "Global"
def outer():
name = "Outer"
def inner():
name = "Inner"
print(name)
inner()
outer()
Output:
Inner
Python finds the nearest matching variable first.
Nested Functions
A function can be defined inside another function.
Example:
def outer():
def inner():
print("Inside inner function")
inner()
outer()
Here inner() is a nested function.
Nested functions are useful when a helper function only makes sense within another function.
Closures
A closure occurs when an inner function remembers values from its enclosing scope.
Example:
def multiplier(x):
def multiply(number):
return number * x
return multiply
double = multiplier(2)
print(double(10))
Output:
20
The multiply() function remembers the value of x.
Closures are useful in advanced Python programming, decorators, and functional programming patterns.
Lambda Functions
A lambda is a small anonymous function.
Basic syntax:
lambda arguments: expression
Example:
square = lambda x: x * x
print(square(5))
Output:
25
The same logic using a normal function would be:
def square(x):
return x * x
When Should You Use Lambda Functions?
Lambda functions are useful when you need a small function temporarily.
They are commonly used with functions such as:
sorted()map()filter()
Example:
numbers = [5, 2, 8, 1]
sorted_numbers = sorted(numbers, key=lambda x: x)
print(sorted_numbers)
For complicated logic, a normal def function is usually easier to read.
Functions as Objects
In Python, functions are objects.
That means you can:
- Store them in variables
- Pass them as arguments
- Return them from other functions
- Store them in lists or dictionaries
Example:
def greet():
print("Hello")
message = greet
message()
Output:
Hello
Here message refers to the same function.
Passing a Function to Another Function
Because functions are objects, you can pass one function to another.
Example:
def greet():
return "Hello"
def execute(function):
print(function())
execute(greet)
Output:
Hello
This concept is important for understanding decorators and higher-order functions.
Higher-Order Functions
A higher-order function is a function that:
- Accepts another function as an argument, or
- Returns another function.
Python includes several built-in higher-order functions.
For example:
numbers = [1, 2, 3, 4]
result = list(map(lambda x: x * 2, numbers))
print(result)
Output:
[2, 4, 6, 8]
Recursive Functions
A recursive function calls itself.
Example:
def countdown(number):
if number <= 0:
return
print(number)
countdown(number - 1)
countdown(5)
Output:
5
4
3
2
1
Every recursive function needs a condition that stops the recursion.
This is called the base case.
Without a proper stopping condition, recursion can continue until Python raises an error.
Factorial Using Recursion
A common educational example is calculating factorial:
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
print(factorial(5))
Output:
120
For many practical tasks, an iterative solution may be simpler or more efficient, so recursion should be used when it improves clarity or matches the problem naturally.
Type Hints in Python Functions
Python allows you to add type hints to function parameters and return values.
Example:
def add(a: int, b: int) -> int:
return a + b
Here:
a: intsuggests thatashould be an integerb: intsuggests thatbshould be an integer-> intindicates the expected return type
Type hints improve:
- Code readability
- Editor support
- Static analysis
- Maintainability
Python does not generally enforce these annotations at runtime by itself.
Type Hints with Strings
Example:
def greet(name: str) -> str:
return f"Hello, {name}"
Usage:
message = greet("Ankit")
print(message)
Type hints become especially useful in larger applications.
Type Hints with Lists
Modern Python allows expressive type annotations.
For example:
def calculate_total(numbers: list[int]) -> int:
return sum(numbers)
This communicates that the function expects a list of integers and returns an integer.
For more complex applications, Python’s typing module provides additional tools.
Function Docstrings
A docstring explains what a function does.
Example:
def calculate_area(length, width):
"""Return the area of a rectangle."""
return length * width
You can inspect the documentation with:
help(calculate_area)
Docstrings are useful for making functions easier to understand and maintain.
Function Naming Best Practices
Use descriptive function names.
Good:
def calculate_total():
pass
Better than:
def ct():
pass
A function name should communicate what the function does.
Python convention generally uses snake_case for function names.
Examples:
calculate_total()
get_user_data()
send_email()
validate_password()
Keep Functions Small
A function should ideally have a clear responsibility.
Instead of:
def process_everything():
# validate user
# calculate price
# save database
# send email
# generate report
pass
you could separate responsibilities:
def validate_user():
pass
def calculate_price():
pass
def save_order():
pass
def send_email():
pass
def generate_report():
pass
This makes testing and maintenance easier.
Practical Example: Calculator Functions
Let’s create a simple calculator using functions:
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
return "Cannot divide by zero"
return a / b
Now:
print(add(10, 5))
print(subtract(10, 5))
print(multiply(10, 5))
print(divide(10, 5))
Output:
15
5
50
2.0
Each function handles one operation.
Practical Example: Calculate a Discount
Suppose an online store needs to calculate the final price after a discount.
def calculate_discount(price, discount):
discount_amount = price * discount / 100
return price - discount_amount
Use it:
final_price = calculate_discount(1000, 10)
print(final_price)
Output:
900.0
This function can now be reused throughout the application.
Practical Example: Check Even or Odd
def is_even(number):
return number % 2 == 0
Use it:
print(is_even(10))
print(is_even(7))
Output:
True
False
Because the function returns a Boolean value, it can also be used in conditions:
if is_even(10):
print("The number is even")
Practical Example: Validate an Email
A simple example:
def is_valid_email(email):
return "@" in email and "." in email
Use:
email = "user@example.com"
if is_valid_email(email):
print("Valid email")
else:
print("Invalid email")
Real applications usually need more robust validation, but this example demonstrates how functions can encapsulate validation logic.
Common Mistakes Beginners Make
1. Forgetting to Call the Function
Defining:
def greet():
print("Hello")
does not execute it.
You need:
greet()
2. Forgetting Parentheses
This:
greet
refers to the function object.
This:
greet()
calls the function.
3. Forgetting return
Consider:
def add(a, b):
a + b
This function does not return the result.
Correct:
def add(a, b):
return a + b
4. Incorrect Indentation
Python uses indentation to define blocks.
Incorrect:
def greet():
print("Hello")
Correct:
def greet():
print("Hello")
5. Using Too Many Global Variables
Global state can make programs harder to understand.
Prefer passing data through function parameters and returning results when appropriate.
Function Best Practices
When writing Python functions, follow these practices:
Give Functions One Clear Responsibility
A function should ideally perform one logical task.
Use Descriptive Names
Use:
calculate_total()
instead of:
calc()
when clarity matters.
Keep Functions Manageable
Very large functions are often difficult to test and maintain.
Use Parameters
Avoid hardcoding values when they should be configurable.
Return Values When Appropriate
Returning data makes functions easier to reuse.
Add Type Hints
Type hints can make larger codebases easier to understand.
Write Docstrings
Document public or complex functions.
Avoid Unnecessary Global State
Pass data through parameters instead.
Python Functions Cheat Sheet
| Concept | Example |
|---|---|
| Define function | def greet(): |
| Call function | greet() |
| Parameter | def greet(name): |
| Argument | greet("Ankit") |
| Return value | return result |
| Default argument | def greet(name="Guest") |
| Keyword argument | greet(name="Ankit") |
| Variable positional arguments | *args |
| Variable keyword arguments | **kwargs |
| Lambda | lambda x: x * 2 |
| Type hint | x: int |
| Return type | -> int |
| Docstring | """Description""" |
| Recursive function | Function calling itself |
Frequently Asked Questions
What is a function in Python?
A function is a reusable block of code designed to perform a specific task.
Why should I use functions?
Functions reduce code duplication and make programs easier to organize, test, read, and maintain.
How do I define a function?
Use the def keyword:
def greet():
print("Hello")
How do I call a function?
Write the function name followed by parentheses:
greet()
What is the difference between a parameter and an argument?
A parameter is the variable defined in the function declaration. An argument is the actual value passed to the function.
What does return do?
return sends a value from the function back to the code that called it.
What are *args and **kwargs?
*args collects variable positional arguments, while **kwargs collects variable keyword arguments.
What is a lambda function?
A lambda is a small anonymous function usually used for short expressions.
What is recursion?
Recursion occurs when a function calls itself.
Are Python functions required to have a return statement?
No. A function can perform an action without explicitly returning a value. In that case, it returns None.
Final Thoughts
Functions are a fundamental part of Python programming.
Once you understand how functions work, you can start writing programs that are much more organized and reusable.
The basic pattern is:
def function_name(parameters):
# code
return result
For example:
def calculate_total(price, quantity):
return price * quantity
total = calculate_total(500, 3)
print(total)
Output:
1500
As you progress, you can learn more advanced concepts such as:
*args**kwargs- Lambda functions
- Closures
- Decorators
- Higher-order functions
- Recursion
- Type hints
- Async functions
However, beginners should first become comfortable with defining functions, passing parameters, returning values, and reusing functions.
These concepts form the foundation for writing clean Python applications and will be used everywhere—from simple scripts to large web applications, automation tools, APIs, data-science projects, and AI applications.




