Python Chapter 3 of 3 Closures, Modules, and More

Closure & LEGB Law
The so-called closure is that when the statements that make up a function are packaged with the execution environment of these statements, the resulting object does
sound a bit complicated, so let’s use a chestnut to help understand it. Suppose we have the following definition in the foo.py module:
#foo.py
filename = "foo.py"

def call_func(f):
return f() #As mentioned earlier, f refers to a function object, and then calls it
1
2
3
4
5
In another func.py module, write this code:
#func.py
import foo #import foo.py

filename = "func.py"
def show_filename():
return "filename: %s" % filename

if name == " main ":
print foo.call_func(show_filename) #Note: The actual location of the call is in the foo.call_func function
1
2
3
4
5
6
7
8
9
When we execute func with the python func.py command .py, the output is:
chiyu@chiyu-PC:~$ python func.py
filename:func.py
1
2
Obviously, the value of the filename variable used by the show_filename() function is in the same environment as it (func.py module ) defined in . Although the filename variable with the same name is also defined in the foo.py module, and the actual call to show_filename is also inside the call_func of foo.py.
For nested functions, this mechanism is more obvious: the closure will capture the entire environment required for the inner function to execute:
#enclosed.py
import foo
def wrapper():
filename = "enclosed.py"
def show_filename():
return "filename: %s" % filename
print foo.call_func(show_filename) #Output: filename: enclosed.py In fact, each function object has a globals
attribute that points to the global namespace where the function is defined:
#show_filename inside wrapper
#show_filename.globals

{
' builtins ': <module ' builtin ' (built-in)>, #Built-in scope environment
' file ': 'enclosed.py',
'wrapper': <function wrapper at 0x7f84768b6578>, #Direct surrounding environment
' package ': None,
' name ': ' main ',
'foo': <module 'foo' from '/home/chiyu/foo.pyc'>, #global environment
' doc ': None

When the code executes to the return "filename: %s" % filename statement in show_filename, the parser looks for the filename variable in the following order:
1.Local - inside the local function (show_filename), assigned by any means, and not global The keyword is declared as the filename variable of the global variable;
2.Enclosing - the local scope of the immediate surrounding space (upper function wrapper), looking for the filename variable (if there are multiple levels of nesting, search from the inside out, until the outermost 3.Global
- global space (module enclosed.py), the filename variable assigned at the top level of the module;
4.Builtin - find the filename variable in the predefined variable names in the built-in module (builtin);
in any layer If the filename variable that meets the requirements is found first, it will not look further to the outer layer. If the required variable is not found until the Builtin layer, a NameError exception is thrown. That's what variable name resolution is for: LEGB's Law.
Summary:
1. The most important use value of closures is: to seal the context of function execution;
2. In the execution environment captured by the closure (the context where the def statement block is located), the closure also follows the LEGB rules to search layer by layer until it finds a match variable required, or an exception is thrown.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326690825&siteId=291194637