Python Tutorial
Python Variable
Python Operators
Python Sequence
Python String
Python Flow Control
Python Functions
Python Class and Object
Python Class Members (properties and methods)
Python Exception Handling
Python Modules
Python File Operations (I/O)
Closures in Python are a way to define a function with behavior that depends on values that are not passed as arguments. In other words, a closure is a function that "remembers" the values of the enclosing function's variables, even after the enclosing function has completed execution.
Here's a tutorial on closures in Python:
To understand closures, you first need to understand nested functions. A nested function is a function defined inside another function. Nested functions can access the variables of the enclosing function:
def outer_function(x): def inner_function(y): return x + y return inner_function add_five = outer_function(5) result = add_five(3) print(result) # Output: 8
In this example, inner_function
is a nested function within outer_function
. When outer_function
is called with the argument 5, it defines inner_function
and returns it. The returned function is then assigned to add_five
.
In the previous example, when add_five(3)
is called, the inner_function
still has access to the x
variable from outer_function
, even though outer_function
has completed execution. This is an example of a closure.
A closure occurs when:
Closures can be useful for creating function factories or decorators. Here's an example of using closures to create a function factory:
def power_factory(power): def calculate_power(number): return number ** power return calculate_power square = power_factory(2) cube = power_factory(3) print(square(4)) # Output: 16 print(cube(4)) # Output: 64
In this example, power_factory
takes a power
argument and returns a new function calculate_power
that calculates the given power of a number. The calculate_power
function has access to the power
variable, even after power_factory
has completed execution. This creates two closure functions, square
and cube
, that remember their respective powers.
If you need to modify the value of a variable from the containing function within the nested function, you can use the nonlocal
keyword:
def counter_factory(): count = 0 def increment_counter(): nonlocal count count += 1 return count return increment_counter counter = counter_factory() print(counter()) # Output: 1 print(counter()) # Output: 2
In this example, the counter_factory
function defines a count
variable and a nested function increment_counter
that increments the count
variable. By using the nonlocal
keyword, the increment_counter
function modifies the count
variable in the containing function.
In summary, closures in Python are functions that remember the values of the enclosing function's variables, even after the enclosing function has completed execution. They are a powerful feature that allows you to create function factories, decorators, and more, with behavior that depends on values that are not passed as arguments.
How to create closures in Python:
def outer_function(x): def inner_function(y): return x + y return inner_function closure = outer_function(5) result = closure(3)
Scope and variable binding in Python closures:
def outer_function(x): def inner_function(y): return x + y return inner_function closure = outer_function(5) result = closure(3) # x is remembered from the outer scope
Lexical scoping and closures in Python:
def outer_function(x): def inner_function(y): return x + y return inner_function closure = outer_function(5) result = closure(3) # Lexical scoping: inner_function has access to x
Nested functions and closures in Python:
def outer_function(x): def inner_function(y): return x + y return inner_function closure = outer_function(5) result = closure(3)
Capturing variables in closures in Python:
def outer_function(x): def inner_function(y): return x + y return inner_function closure = outer_function(5) result = closure(3) # Capturing variable x in the closure
Closures and data encapsulation in Python:
def create_counter(): count = 0 def increment(): nonlocal count count += 1 return count return increment counter = create_counter() result = counter() # Accessing and modifying encapsulated data
Dynamic behavior of closures in Python:
def outer_function(x): def inner_function(y): return x + y return inner_function closure = outer_function(5) result = closure(3) # Changing the value of x dynamically closure.__closure__[0].cell_contents = 10 result_updated = closure(3)