Reference: http://python.jobbole.com/81683/
-
Python’s Namespace Any variable is created within its own namespace. If your own namespace doesn’t contain this name, a new one will be created, rather than overriding the upper namespace. When accessing, if your namespace doesn’t contain it, the upper namespace will be accessed.
-
Python’s Closures Any function is an object. You can create a callable object. If you create a callable function that uses a local variable in its internal process, this involves a closure: a function nested and defined in a non-global scope can remember the enclosing namespace where it was defined.
In simple terms: a child function can use local variables from its parent function, and this behavior is called a closure.
-
Closure Details in C++ vs Python In most languages, a parent function’s local variables end their lifecycle when the parent function exits. When lambda functions or function objects reference these local variables, problems can arise. If a lambda or function object can remember the current namespace during its definition, that’s a closure. In C++, local variable lifecycles are the same as their parent function, so what to do? Use the mutable modifier, which makes the variable’s lifecycle as long as the function object or lambda expression, otherwise capturing these variables might cause problems. Python captures all objects in the closure, preventing their release until the function object is collected.
-
Decorators Sometimes we need to modify functions in similar ways. For example, we might want to calculate a function’s execution time by adding timestamps at the beginning and end, then printing at the end. Or we might need to validate parameters and return values. We could call validation functions at the start and end of each function.
Decorators can accomplish this. For example, if we have a function:
def func():
time.sleep(1)
We can use another function that returns a function object with closure to achieve this:
def addTimePrint(func):
def retFuncObj(*args, **kwargs):
starttime = time()
func(*args, **kwargs)
print(time() - starttime)
return retFuncObj
Then we need to replace the original func function:
func = addTimePrint(func)
Python provides syntactic sugar: after defining addTimePrint, use @addTimePrint to complete both function definition and decoration:
@addTimePrint
def func():
time.sleep(1)