16.Functions II — Scope, Closures, *args/**kwargs

In this section, we dive deeper into Python functions by exploring scope rules, closures, and variadic arguments (*args and **kwargs). Understanding these concepts is essential for writing clean, maintainable, and powerful Python code.

1. Scope Rules (LEGB)

Python uses the LEGB rule to resolve variable names:

  • L – Local: Names defined inside the current function.
  • E – Enclosing: Names in enclosing functions (nested functions).
  • G – Global: Names defined at the top-level of a module.
  • B – Built-in: Names preassigned in Python (e.g., len, range).

Example:

x = ‘global’

def outer():
    x = ‘enclosing’
    def inner():
        x = ‘local’
        print(x)
    inner()

outer()  # Output: local

Best Practice: Avoid excessive reliance on global variables; prefer passing arguments explicitly.

2. Closures

A closure occurs when a nested function captures variables from its enclosing scope even after the outer function has finished executing.

Example:

def make_multiplier(factor):
    def multiply(x):
        return x * factor
    return multiply

times3 = make_multiplier(3)
print(times3(10))  # Output: 30

Closures are useful for creating function factories and maintaining state without using global variables.

3. Variadic Arguments: *args and **kwargs

*args allows a function to accept any number of positional arguments as a tuple. **kwargs allows any number of keyword arguments as a dictionary.

Example:

def demo(*args, **kwargs):
    print(“Positional:”, args)
    print(“Keyword:”, kwargs)

demo(1, 2, 3, name=’Alice’, age=30)

Best Practice: Use *args and **kwargs for flexible APIs, but document expected arguments clearly.

Advanced Features and Best Practices

Use closures for decorators and callbacks.

  • Understand LEGB to avoid NameError and unintended shadowing.
  • Avoid modifying global state inside functions.
  • Combine *args and **kwargs with keyword-only arguments for clarity.
Scroll to Top
Tutorialsjet.com