A closure is a nested function that can access free variables from an enclosing function even after it has finished its execution. We know that, like nested function definitions, lambda expressions can reference values from the enclosing scope, so lambda expressions are also useful as a closure.
def func(x, username): if x < 0: return lambda: print('Hello', username) elif x > 0: return lambda: print('Hi', username) else: return lambda: print('Hey', username) f1 = func(6, 'Sam') f1() f2 = func(0, 'Tim') f2()
Output-
Hi Sam
Hey Tim
We can use the parameter username inside the lambda expression, so here these lambda expressions act as closures. Here is one more example:
def func(symbol): return lambda message: print(message + symbol) exclaim = func('!!!!!') question = func('???') sentence = func('.') exclaim('OMG') question('What is this') sentence('Python is easy') exclaim('Really')
Output-
OMG!!!!!
What is this???
Python is easy.
Really!!!!!
The lambda expression remembers the value of the symbol from the enclosing scope even after the flow of control is not in that scope; thus, it acts as a closure.
The function func returns a function object. That function object is created by the lambda expression. message is the parameter of the lambda expression and symbol is the parameter of the function func. We have called the function func 3 times, first time with argument '!!!!!', second time with argument '???' and third time with argument '.'. These arguments will be assigned to the parameter symbol when func is called.
When the function func is executed, the lambda expression creates a function object which is returned by func. We have assigned the returned function objects to the names exclaim, question, and sentence. These names now act like functions and we call them with different arguments. The arguments that are sent to these function calls, are assigned to the parameter message of lambda expression.