Functions — Arguments, Returns & Scope
Defining Functions
def greet(name):
return f"Hello, {name}!"
message = greet("Digamber")
print(message) # Hello, Digamber!A function without an explicit return returns None. Functions are values too — you can pass them around like any other object.
Default & Keyword Arguments
def connect(host, port=5432, timeout=10):
...
connect("localhost") # uses both defaults
connect("localhost", 3306) # positional
connect("localhost", timeout=30) # keyword — skip the middle argThe classic trap: never use a mutable default. It’s created once and shared between calls:
# WRONG — the same list is reused on every call
def add_item(item, items=[]):
items.append(item)
return items
# RIGHT
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items*args and **kwargs
Accept any number of positional or keyword arguments:
def log(*args, **kwargs):
print("positional:", args) # a tuple
print("keyword:", kwargs) # a dict
log(1, 2, 3, level="info", user="ravi")
# positional: (1, 2, 3)
# keyword: {'level': 'info', 'user': 'ravi'}The same stars unpack when calling:
coords = (28.6, 77.2)
point(*coords) # point(28.6, 77.2)
config = {"host": "db", "port": 5432}
connect(**config) # connect(host="db", port=5432)Returning Multiple Values
def min_max(numbers):
return min(numbers), max(numbers) # returns a tuple
low, high = min_max([3, 1, 4, 1, 5])Scope — the LEGB Rule
Python resolves names in order: Local → Enclosing → Global → Built-in. Reading outer variables works automatically; assigning to them creates a new local unless you say otherwise:
count = 0
def increment():
global count # required to ASSIGN to a module-level name
count += 1Needing global is usually a design smell — prefer returning values or using a class.
Type Hints — Modern Python Style
Hints don’t change runtime behaviour, but editors and type checkers (mypy, pyright) use them to catch bugs before you run anything:
def split_bill(total: float, people: int) -> float:
return round(total / people, 2)
def find_user(user_id: int) -> "User | None":
...Professional Python in 2026 is typed Python. Start the habit now.