Closures: ========= what is closure? ================ def fun1(): # outer function def fun2(): # inner function implementation ==> closure is a nested function which has access to a variable from an enclosing function that has finished its execution. ==> A variables which want access with the enclosed function is not bound to the local scope. ==> To use immutable variable (number, string, Boolean etc.), we have to use the "non-local" keyword. Advantage of Closure: ===================== 1) we can help to avoid the using global values and provide some form the data hiding. 2) Can use in decorators. Nested Function: ================ def fun1(): print("This is the outer function") def fun2(): print("This is the inner function") print("Hi") print("Good Morning") print("Welcome To Ashok IT") fun2() fun1() Variable Scope: =============== def outer(p): q = 100 def inner(r): return p + q + r return inner cl = outer(112) result = cl(121) print(result) ===================================== def fun1(name):# name = "Python" name = "Ashok IT" # modification of parameter value def fun2(): print(name) return fun2 result = fun1("Python") # result = fun2 function aliasing result() ======================================== nonlocal keyword: ================= ==> this allows a variable outside the local scope to be accessed. ==> can use in closures. to modify an immutable variable present in the scope of outer variable. def f1(): counter = 0 # immutable def f2(): nonlocal counter counter = counter + 1 return counter return f2 closure = f1() # function aliasing result = closure() print("Result = ",result) result = closure() print("Result = ",result) result = closure() print("Result = ",result) result = closure() print("Result = ",result)