Python Functions
A function is a named block of code that you can run whenever you need it. Functions remove repetition, give a name to an idea, and make code easy to test. Every practice program becomes cleaner once it is wrapped in a function.
- Define and call functions
- Pass positional, keyword and default arguments
- Return one or several values
- Accept any number of arguments with *args and **kwargs
Define and call a function
def starts a function, followed by its name, brackets and a colon. The indented block is the body. Nothing runs until you call the function.
def greet(): print("Hello from a function") greet()greet()Hello from a function Hello from a function
Parameters and arguments
Parameters are the names in the definition; arguments are the values you pass in the call.
def greet(name, course): print(f"Hi {name}, welcome to {course}") greet("Asha", "Python")greet(course="Playwright", name="Ravi") # keyword arguments: any orderHi Asha, welcome to Python Hi Ravi, welcome to Playwright
Return a value
return sends a value back to the caller and ends the function. A function without return gives back None.
def area(width, height): return width * height def show(x): print("value:", x) a = area(3, 4)print(a, area(5, 5) + 1)print(show(7))12 26 value: 7 None
Return several values as a tuple and unpack them:
def stats(numbers): return min(numbers), max(numbers), sum(numbers) / len(numbers) low, high, avg = stats([4, 8, 15, 16, 23, 42])print(low, high, round(avg, 2))4 42 18.0
Prefer functions that return a result over functions that print it. A returned value can be tested, stored or printed later; printed text is gone.
Default arguments
A default value is used when the caller leaves the argument out. Parameters with defaults must come after those without.
def connect(host, port=443, secure=True): scheme = "https" if secure else "http" return f"{scheme}://{host}:{port}" print(connect("sqatools.in"))print(connect("localhost", 8080, secure=False))https://sqatools.in:443 http://localhost:8080
Never use a mutable value such as [] as a default. It is created once, when the function is defined, and shared by every call:
def add_item(item, basket=[]): # bug basket.append(item) return basket print(add_item("pen"))print(add_item("book")) # the old pen is still there def add_item_fixed(item, basket=None): # fix if basket is None: basket = [] basket.append(item) return basket print(add_item_fixed("pen"), add_item_fixed("book"))['pen'] ['pen', 'book'] ['pen'] ['book']
*args: any number of positional arguments
A parameter with one * collects extra positional arguments into a tuple.
def total(*prices): print(type(prices).__name__, prices) return sum(prices) print(total(10, 20, 30))print(total())tuple (10, 20, 30) 60 tuple () 0
**kwargs: any number of keyword arguments
Two ** collect extra keyword arguments into a dictionary.
def build_url(base, **params): query = "&".join(f"{k}={v}" for k, v in params.items()) return f"{base}?{query}" if query else base print(build_url("https://api.example.com/users", page=2, limit=50))print(build_url("https://api.example.com/users"))https://api.example.com/users?page=2&limit=50 https://api.example.com/users
Unpack arguments in a call
and * also work the other way: they spread a list or dict into separate arguments.
def describe(name, role, city): return f"{name} ({role}) from {city}" row = ["Meena", "tester", "Pune"]info = {"name": "Ravi", "role": "dev", "city": "Delhi"}print(describe(*row))print(describe(**info))Meena (tester) from Pune Ravi (dev) from Delhi
Docstrings and type hints
def discount(price: float, percent: float = 10) -> float: """Return the price after taking off `percent` per cent.""" return round(price * (1 - percent / 100), 2) print(discount(499.0))print(discount.__doc__)449.1 Return the price after taking off `percent` per cent.
Type hints (price: float, -> float) document what the function expects. Python does not enforce them, but IDEs and tools such as mypy use them to catch mistakes.
Functions are objects
A function can be stored in a variable, put in a list, or passed to another function:
def shout(text): return text.upper() + "!" def whisper(text): return text.lower() + "..." for style in [shout, whisper]: print(style.__name__, "->", style("Hello")) print(sorted(["banana", "fig", "apple"], key=len))shout -> HELLO! whisper -> hello... ['fig', 'apple', 'banana']
Check your understanding
Predict the output
def f(a, b=2, *rest, **opts): return a, b, rest, opts print(f(1))print(f(1, 5, 6, 7, debug=True))(1, 2, (), {})
(1, 5, (6, 7), {'debug': True})a and b take the first two values, *rest collects any extra positional values into a tuple, and **opts collects keyword arguments into a dict.
Quick quiz
1. What does a function return if it has no return statement?
Every function returns something; without return it is None.
2. Which definition is valid?
Parameters with defaults must come after those without.
3. Inside def f(*args), what type is args?
*args collects positional arguments into a tuple; **kwargs gives a dict.
4. Why is def f(items=[]) a problem?
The default is created once, so changes persist across calls. Use None instead.
Exercise: is it a palindrome?
Write is_palindrome(text) that ignores case and spaces, and returns True or False.
"Never odd or even", "Python"
Never odd or even -> True Python -> False
Hint 1
Clean the text first: "".join(text.lower().split()).
Hint 2
Compare the cleaned text with its reverse [::-1].
def is_palindrome(text): cleaned = "".join(text.lower().split()) return cleaned == cleaned[::-1] for t in ["Never odd or even", "Python"]: print(t, "->", is_palindrome(t))Never odd or even -> True Python -> False
split() with no arguments removes all spaces and join glues the words back together. The function returns the comparison result directly, so callers can use it in if statements.
Program Practice
39 Python Function Programs
Every program has a step-by-step explanation, colour-coded code and its real output.
Python functions FAQ
What is the difference between a parameter and an argument?
A parameter is the name in the function definition (def greet(name)). An argument is the value passed in a call (greet("Asha")).
What are *args and **kwargs in Python?
args collects extra positional arguments into a tuple; kwargs collects extra keyword arguments into a dict. The names are conventions; the and do the work.
Can a Python function return multiple values?
Yes. return a, b returns a tuple, which the caller can unpack: x, y = f().
What is the difference between print and return in a function?
print shows text on the screen. return hands a value back to the caller so it can be used in further code.