Python Functions
A function is a reusable block of code that performs a specific task. It only runs when it is "called."
-
Input: Arguments.
-
Process: Function Logic.
-
Output: Return Value.
2. Why Functions Matter
-
Reusability (DRY - Don't Repeat Yourself): Write the logic once, use it everywhere.
-
Modularity: Break a complex 1000-line program into 10 small, manageable functions.
-
Maintainability: If the logic changes, you only update it in one place.
-
Namespace Management: Helps avoid variable name conflicts (Scoping).
3. Basic Syntax & Execution
1. Defining a Function
We use the def keyword followed by the function name and parentheses.
def say_hello():
"""This function prints a greeting message."""
print("Hello! Welcome to Python.")
2. Calling a Function
The function won't execute until you call it by its name.
say_hello()
4. Parameters vs. Arguments
-
Parameter: The variable listed inside the parentheses in the def line (the placeholder).
-
Argument: The actual value sent to the function when it is called (the real data).
def greet(name): # 'name' is the Parameter
print(f"Hi {name}")
greet("Rajkumar") # "Rajkumar" is the Argument
5. The return Statement
print() only shows a value on your screen. return sends a value back to the program so it can be stored and used later.
def add(a, b):
return a + b
result = add(5, 10)
print(result * 2) # Output: 30
> A function stops the moment it hits a return. Any code written after it is ignored.
6. Argument Variations
1. Default Arguments
Provide a fallback value if the user forgets to pass an argument.
def power(num, exp=2):
return num ** exp
print(power(4)) # 16 (uses default 2)
print(power(4, 3)) # 64 (uses provided 3)
2. Keyword Arguments
Specify which value goes to which parameter. Order doesn't matter here.
def describe_pet(animal_type, pet_name):
print(f"I have a {animal_type} named {pet_name}.")
describe_pet(pet_name="Bruno", animal_type="Dog")
3. Arbitrary Arguments *args
Used when you don't know how many positional arguments will be passed. Stores them as a tuple.
def total_sum(*numbers):
return sum(numbers)
print(total_sum(1, 2, 3, 4, 5))
4. Arbitrary Keyword Arguments **kwargs
Used for unknown named arguments. Stores them as a dictionary.
def user_profile(**data):
for key, value in data.items():
print(f"{key}: {value}")
user_profile(username="coder_x", level="Admin")
7. Function Scope - LEGB Rule
Scope determines where a variable is accessible. Python follows the LEGB rule:
-
Local: Inside the function.
-
Enclosing: Inside nested functions.
-
Global: At the top level of the script.
-
Built-in: Python's internal names (like len).
8. Lambda Functions - Anonymous
For short, one-time-use logic.
- Syntax: lambda arguments : expression
square = lambda x: x * x
print(square(5)) # 25
9. Recursion
A function that calls itself to solve smaller pieces of a problem.
- Base Case: Necessary to stop the recursion (prevents RecursionError).
def factorial(n):
if n == 1: return 1 # Base Case
return n * factorial(n - 1)
10. Advanced - Decorators
Decorators allow you to "wrap" another function to add extra behavior without changing its code.
def my_decorator(func):
def wrapper():
print("Starting task...")
func()
print("Task complete.")
return wrapper
@my_decorator
def say_hi():
print("Hi!")
11. Generators and yield
Generators are memory efficient. Unlike return, yield pauses the function and saves its state to continue later.
def count_to_three():
yield 1
yield 2
yield 3
for num in count_to_three():
print(num)
ConceptKey KeywordPurpose****Standard FunctiondefLogical encapsulation.Data OutputreturnSending results back.Default Argparam=valHandling missing inputs.Variable Args*args / **kwargsHandling unknown number of inputs.One-LinerlambdaQuick, small logic.Memory SaveryieldHandling massive data streams.Behavior Mod@decoratorAdding logic to existing functions.