Back to Blog
Python

Python def Keyword: Defining Functions

python def keyword: Learn how the Python def keyword defines functions, handles parameters, return values, scope, and decorators with practical examples.

PythonFunction definitionPython syntaxDecoratorsFunction scope
Illustration of Python function definition with def keyword and code blocks.

The python def keyword is the primary way to define a function in Python. When the interpreter encounters a def statement, it creates a function object and binds it to the given name in the current scope. The syntax is straightforward:

def function_name(parameters): """Optional docstring.""" # function body return value

The function body is indented, and the return statement is optional. If omitted, the function returns None. This is the foundation of almost every Python program, so understanding how def behaves is essential.

The def Keyword and Function Syntax

A function definition consists of the def keyword, a name, a parameter list in parentheses, and a colon. The body must be indented. The name follows the same rules as any identifier: it can contain letters, digits, and underscores, but cannot start with a digit. The parameter list can be empty, but the parentheses are required.

def greet(): print("Hello, world!") greet() # Output: Hello, world!

The function object created by def is a first-class object. You can assign it to another variable, pass it as an argument, or return it from another function. This is the basis for higher-order functions and decorators.

Parameters and Argument Passing

Python supports several kinds of parameters. The simplest are positional parameters, which are matched to arguments by order. You can also use keyword arguments, where the caller specifies the parameter name.

def describe_person(name, age, city="Unknown"): print(f"{name} is {age} years old and lives in {city}.") describe_person("Alice", 30) describe_person("Bob", 25, city="Paris")

Default values are evaluated once at function definition time, which matters when the default is a mutable object like a list or dictionary. A common mistake is using a mutable default and modifying it, which persists across calls. Use None as the default and create a new object inside the function instead.

For variable-length arguments, *args collects extra positional arguments into a tuple, and **kwargs collects extra keyword arguments into a dictionary. This is useful for wrappers and decorators.

def log(level, *messages, **metadata): print(level, messages, metadata) log("INFO", "start", "end", user="alice")

Return Values and the None Default

A function can return any Python object using the return statement. If no return is executed, or if return is written without a value, the function returns None. To return multiple values, return a tuple, which can be unpacked by the caller.

def min_max(numbers): return min(numbers), max(numbers) low, high = min_max([3, 1, 4, 1, 5])

The return statement immediately exits the function. Code after a return in the same block is unreachable. This is often used for early exits in validation logic.

Scope, Global, and nonlocal

Names defined inside a function are local to that function. They do not collide with names in the outer scope. To modify a global variable, you need the global declaration. For nested functions, nonlocal allows assignment to a variable in the enclosing function's scope.

counter = 0 def increment(): global counter counter += 1 def outer(): value = 10 def inner(): nonlocal value value += 1 inner() print(value)

Understanding scope is critical when writing closures, which are functions that capture variables from their enclosing scope. Closures are the foundation of decorators.

Closures and Decorators

A closure is created when a nested function references a variable from its enclosing function. The function object retains access to that variable even after the outer function has returned. This is used to create stateful functions.

def make_multiplier(factor): def multiplier(x): return x * factor return multiplier double = make_multiplier(2) print(double(5)) # 10

Decorators are a syntactic way to apply a wrapper function to another function. The def keyword defines both the decorator and the function being decorated. A decorator takes a function as an argument, returns a new function, and the @ syntax applies it.

def uppercase_decorator(func): def wrapper(*args, **kwargs): result = func(*args, **kwargs) return result.upper() return wrapper @uppercase_decorator def greet(): return "hello" print(greet()) # HELLO

Decorators are widely used for logging, timing, access control, and caching. They rely on the fact that def creates a callable object that can be passed around.

Function Call Overhead and When to Use def

Every function call in Python has a small overhead: argument binding, stack frame creation, and cleanup. For most applications this is negligible, but in tight loops or performance-critical code, it can matter. If you are repeatedly calling a tiny function millions of times, inlining the logic might be faster. However, clarity and maintainability usually outweigh micro-optimizations.

The lambda expression can define a small anonymous function, but it is limited to a single expression and cannot contain statements. Use def when you need multiple statements, docstrings, or a named function that can be reused and tested. Lambdas are best for short, throwaway functions passed to map, filter, or sorted.

Type Hints and Documentation

Modern Python supports type hints, which are optional annotations that describe the expected types of parameters and return values. They are not enforced at runtime but help with static analysis and documentation. Including a docstring inside the function body is a good practice for maintainability.

def add(a: int, b: int) -> int: """Return the sum of two integers.""" return a + b

Type hints and docstrings make the function's contract explicit, which is especially valuable in large codebases. The def keyword itself does not enforce types, but it is the place where you declare the interface.

python def keyword: Practical Usage and Code Examples | RYUSLOG DEV