Course topics

By WebNest Studio Engineering Team

Python Tutorial

Python Functions

A function is a named, reusable block of code that performs a specific task. Functions let you avoid repeating yourself, organize a program into logical pieces, and give each piece a clear name and purpose. In Python, functions are defined with the def keyword and are themselves first-class objects — they can be assigned to variables, passed as arguments, and returned from other functions.

Python's function syntax also supports flexible argument handling that goes well beyond a fixed parameter list, including default values and mechanisms for accepting an arbitrary number of arguments, which makes Python functions unusually adaptable compared to many statically typed languages.

Why it matters

Functions are how a program is divided into named, reusable, testable pieces. Without them the same code is copied in several places, and a fix has to be made in each. Every library you use is a set of functions, and writing your own clearly is the main difference between a script and maintainable software.

Defining Functions and return

A function is defined with def function_name(parameters): followed by an indented block. The return statement sends a value back to the caller and immediately exits the function; a function with no explicit return statement (or a bare "return") returns None automatically. Parameters listed in the def line become local variables inside the function body.

Default Arguments

A parameter can be given a default value in the function definition, e.g. def greet(name, greeting="Hello"):. If the caller omits that argument, the default is used; if the caller supplies it, the supplied value overrides the default. Default argument values are evaluated only once, when the function is defined — using a mutable default like a list can lead to a well-known and surprising bug.

*args and **kwargs

To accept an arbitrary number of positional arguments, a parameter prefixed with a single asterisk, *args, collects any extra positional arguments into a tuple. To accept an arbitrary number of keyword arguments, a parameter prefixed with two asterisks, **kwargs, collects them into a dictionary of name-value pairs. These are commonly combined with regular parameters to build flexible, general-purpose functions.

Docstrings

A docstring is a string literal — typically triple-quoted — placed as the very first statement inside a function, class, or module, describing what it does. Unlike an ordinary comment, a docstring is stored by Python as the object's __doc__ attribute and can be retrieved at runtime with help(function_name) or function_name.__doc__, which is why writing clear docstrings matters for any code others will use.

Examples

Default arguments, *args, and **kwargs together

Python
def describe_pet(name, species="dog", *tags, **details):
    """Print a description of a pet using flexible arguments."""
    print(f"{name} is a {species}.")
    if tags:
        print("Tags:", ", ".join(tags))
    for key, value in details.items():
        print(f"{key}: {value}")

describe_pet("Rex")
describe_pet("Milo", "cat", "friendly", "indoor", age=3, color="black")
Output
Rex is a dog.
Milo is a cat.
Tags: friendly, indoor
age: 3
color: black

A function with a return value and a docstring

Python
def area_of_circle(radius):
    """Return the area of a circle given its radius."""
    pi = 3.14159
    return pi * radius ** 2

result = area_of_circle(4)
print(result)
print(area_of_circle.__doc__)
Output
50.26544
Return the area of a circle given its radius.

Common Mistakes

  • Using a mutable object like a list or dict as a default argument value, which is shared across all calls instead of being freshly created each time.
  • Forgetting that a function without a return statement returns None, and then trying to use that None as if it were a meaningful result.
  • Mixing up the order of parameters — positional parameters, then *args, then keyword-only/default parameters, then **kwargs — which causes a SyntaxError if arranged incorrectly.
  • Writing an ordinary comment instead of a proper triple-quoted docstring as the first line of a function meant to be documented.

Exercise

Write greet, which takes a name and an optional greeting that defaults to Hello, and total, which accepts any number of numbers and returns their sum.

Expected output: Hello, Asha!, Welcome, Ravi!, 6 (one per line)

Python · starter code
# TODO: define greet(name, greeting="Hello") that returns e.g. "Hello, Asha!"

# TODO: define total(*numbers) that returns the sum of its arguments


print(greet("Asha"))
print(greet("Ravi", greeting="Welcome"))
print(total(1, 2, 3))
Show hints
  • A default value is written in the parameter list: def greet(name, greeting="Hello"):.
  • Inside the function, *numbers is a tuple, so sum(numbers) adds its items.
Show solution
Python · solution
def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"


def total(*numbers):
    return sum(numbers)


print(greet("Asha"))
print(greet("Ravi", greeting="Welcome"))
print(total(1, 2, 3))

Quick quiz

1. What does a function return when it has no return statement?

  • A. 0
  • B. None
  • C. An empty string
  • D. It raises an error
Show answer

B. Every function returns a value; without an explicit return it is None.

2. Inside def f(*args):, what type is args?

  • A. list
  • B. set
  • C. dict
  • D. tuple
Show answer

D. The extra positional arguments are collected into a tuple.

3. Inside def f(**kwargs):, what type is kwargs?

  • A. dict
  • B. tuple
  • C. list
  • D. set
Show answer

A. The extra keyword arguments are collected into a dictionary of name to value.

Interview questions

What are *args and **kwargs?

Show answer

They let a function accept a variable number of arguments. *args collects extra positional arguments into a tuple, and **kwargs collects extra keyword arguments into a dictionary. The names are a convention; the asterisks are what matter. They are used for functions such as print that take any number of values, and for wrappers that pass arguments on to another function.

How does a Python function return more than one value?

Show answer

It returns a tuple. return a, b packs the two values into one tuple, and the caller can unpack it with x, y = function(). For more than two or three values, a named tuple, a dataclass or a dictionary is clearer, because the caller does not have to remember the order.

Key Points to Remember

  • Functions are defined with def and can return a value with return; no return means the function returns None.
  • Default argument values let callers omit certain arguments, but mutable defaults are evaluated once and shared — a classic pitfall.
  • *args collects extra positional arguments into a tuple; **kwargs collects extra keyword arguments into a dictionary.
  • A triple-quoted docstring as the first statement in a function documents it and is accessible via help() or __doc__.

Practice in the playground

Write and run your own code for this topic, or start from the exercise or an example. Runs Python in your browser. Your code for each topic is kept in this browser.

Run the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.

WebNest Studio

Written by

WebNest Studio Engineering Team

Practical lessons from developers working with Java, Python, React, databases and production systems.

Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering