In Python, even if the enclosing function has stopped running, a closure—a nested function—captures and remembers the values of variables in the local scope of the surrounding function. This enables a closure "closes over" the variables it requires, therefore enabling them to continue past the lifespan of the enclosing function.
Usually defining a nested function within another function and returning that nested function helps you to generate a closure.
def outer_function(x):
def inner_function(y):
return x + y
return inner_function
closure = outer_function(10)
result = closure(5)
print(result) # Output: 15
Within this case, inner_function is defined inside outer_function. When outer_function is called with an argument of 10 it returns inner_function, which is subsequently assigned to the closure variable. Later, when closure is called with a 5 argument, it still has access to the x variable from its enclosing scope, producing the output 15.
Why do you use closures?
Closures have great application in many different contexts, including:
Closures allow one to create specialized functions depending on certain starting configuration or parameters. When you need to build several like functions with varying settings, this is quite helpful.
In event-driven programming, closures are frequently used to generate callback functions with further context or state information.
Closures allow you to encapsulate data within a function therefore generating a private scope for that data. This keeps data integrity intact and helps to stop accidental changes.
Modifying the behavior of functions without changing their code is the decorator pattern.
Closures can be used to cache the outcomes of costly function calls, therefore reducing needless re-computation and hence enhancing efficiency.
Let us now examine some Python code samples to grasp closures more fully.
def exponentiate(power):
def inner(base):
return base ** power
return inner
square = exponentiate(2)
cube = exponentiate(3)
print(square(4)) # Output: 16
print(cube(4)) # Output: 64
Data Encapsulation
def counter():
count = 0
def increment():
nonlocal count # Use nonlocal to modify the count variable in the enclosing scope
count += 1
return count
def decrement():
nonlocal count
count -= 1
return count
return increment, decrement
inc, dec = counter() # Get closures for increment and decrement
print(inc()) # Output: 1
print(inc()) # Output: 2
print(dec()) # Output: 1
In programming, closures are a potent idea found in both Python and many other languages. They let variables in their enclosing scope remain accessible even after the outer function has finished running.
In Python, even if the enclosing function has stopped running, a closure—a nested function—captures and remembers the values of variables in the local scope of the surrounding function. This enables a closure "closes over" the variables it requires, therefore enabling them to continue past the lifespan of the enclosing function.
Usually defining a nested function within another function and returning that nested function helps you to generate a closure.
Closures: How They Function
To show how closures operate in Python, let us first consider a basic case:
Within this case, inner_function is defined inside outer_function. When outer_function is called with an argument of 10 it returns inner_function, which is subsequently assigned to the closure variable. Later, when closure is called with a 5 argument, it still has access to the x variable from its enclosing scope, producing the output 15.
Why do you use closures?
Closures have great application in many different contexts, including:
Closures allow one to create specialized functions depending on certain starting configuration or parameters. When you need to build several like functions with varying settings, this is quite helpful.
In event-driven programming, closures are frequently used to generate callback functions with further context or state information.
Closures allow you to encapsulate data within a function therefore generating a private scope for that data. This keeps data integrity intact and helps to stop accidental changes.
Modifying the behavior of functions without changing their code is the decorator pattern.
Closures can be used to cache the outcomes of costly function calls, therefore reducing needless re-computation and hence enhancing efficiency.
Let us now examine some Python code samples to grasp closures more fully.
Data Encapsulation