The following small series for everyone to bring a python advanced _ about the namespace and scope (detailed). Small series feel very good, now share to everyone, also for everyone to make a reference. Let's take a look at it with a little knitting.
Write in front
If not specifically stated, the following are based on Python3
Namespaces are associated with binding to names, and can be combined with another article that introduces Python names, objects, and their bindings.
1. Namespaces
1.1 What is a namespace
The namespace namespace, also known as the namespace, is a mapping from a name to an object. In Python, most namespaces are implemented by dictionaries, but the implementation of namespaces is not involved in this article. One of the major functions of namespaces is to avoid name collisions:
Def fun1 (): i = 1def fun2 (): i = 2
Of the two functions in the same module, there is absolutely no relationship between the two names of the same name I, because they belong to different obviously space.
1.2 Types of namespaces
The common namespaces are:
A collection of built-in names, including functions such as ABS (), and built-in exception names. In general, use the word built-in to represent this namespace-built-in namespaces
Module Global name collection, directly defined in the module name, such as classes, functions, imported other modules and so on. Typically, a global namespace representation is used.
The name collection in the function call procedure, the parameters in the function, the name of the function body definition, etc., are "activated" when the function is called, constituting a namespace. Typically, a local namespace representation is used.
A collection of properties for an object, which also forms a namespace. However, it is common to use Objname.attrname's indirect way to access properties rather than direct access, so it is not included in the namespace discussion.
The namespace defined by the class, usually when the interpreter enters the class definition, executes to a class ClassName: statement and creates a new namespace. (See official description of the class definition)
1.3 Life cycle of namespaces
Different types of namespaces have different lifecycles:
Built-in namespaces, created when the Python interpreter starts, and destroyed when the interpreter exits;
Global namespace, where the module's global namespace is created when the module definition is read by the interpreter and destroyed when the interpreter exits;
Local namespaces, where you distinguish between functions and class definitions. The local namespace of the function, created when the function is called, or destroyed by an uncaught exception, the namespace defined by the class, which is destroyed when the interpreter reads the class definition creation and the class definition ends. (about the namespace defined by the class, destroyed after the end of the class definition, but actually the class object is the wrapper for the namespace content, see official description of the class definition)
2. Scope
2.1 What is a scope
The scope is a piece of Python text area where namespaces can be "accessed directly". Direct access here refers to an absolute reference (unqualified reference) that attempts to find the name in the namespace. It is necessary to explain the following direct and indirect references:
A direct reference to a direct use of a name, such as name, that attempts to search for the name in the namespace.
Indirect reference, using a form such as Objname.attrname, which is a property reference, does not search for the name Attrname in the namespace, but instead searches for the name objname and then accesses its properties.
2.2 Relationship to namespaces
Now, the namespace holds the name. The scope is a piece of Python text area, that is, a piece of code area, need code region reference name (access variable), then the inevitable scope and the namespace is connected.
As the name implies, the names scope is the area of code text that the name can affect, and the scope of the namespace is the area of code text that the namespace can affect. Then there is a code text area where multiple namespaces can affect it.
The scope is only the text area, its definition is static, and the namespace is dynamic, and the namespaces are generated only as the interpreter executes. Then, the name in the dynamic namespace is accessed in a static scope, causing the dynamic nature of the scope usage.
Well, you can think of it this way:
A static scope is one or more namespaces that affect the area of code by a certain number of rules, and runtime dynamic scopes are namespaces that are combined by a particular level.
To some extent, a dynamic scope is considered a namespace. In the following statement, I will equate dynamic scopes with their corresponding namespaces.
2.3 Name Search Rules
When a name is referenced in the program, how does Python search for that name?
At least three namespaces can be accessed directly when the program is running:
Local
The first search, which contains the inner (innermost) scope of the local name, such as the internal local scope of the function/method/class;
Enclosing
The scope of any enclosing function that contains a non-local (nonlocal) non-Global (Nonglobal) name, based on a nested hierarchy, searching from inside out. As two nested functions, the scope of the inner function is local scope, and the outer function scope is the enclosing scope of the inner layer function;
Global
The second countdown is searched, containing the scope of the current module global name;
Built-in
The last one is searched, containing the outermost scope of the built-in name.
When the program runs, the LGB three scopes are certain, and the e-scope does not exist; If the program is:
i = 1print (i)
Where is the local scope? We think (Python Scopes and namespaces):
Usually, the local scope references the local names of the (textually) current function. Outside functions, the local scope references the same namespace as the Global scope:the module ' s namespace. Class definitions Place yet another namespace in the local scope.
In general, local scopes refer to the names defined in the function. Functions, local scopes and global scopes refer to the same namespace: The star space of the module. However, the local scope of the type refers to the class definition new namespace.
Python searches for names in four scopes in order of the above l-e-g-b. Python throws a Nameerror exception when no search is reached.
2.4 When to introduce scopes we know:
We know:
In Python, a name can be referenced only after it is defined.
Print (i)
Directly referencing the undefined name I, according to the search rule, none of the LGB three scopes searched for the name I (lb same namespace). Throw Nameerror Exception:
Traceback (most recent): File "scope_test.py", line <module> print (i) Nameerror:name ' am not Defined
What about this piece of code?
Def try_to_define_name (): The function defines the name I, and binds an integer object 1 " i = 1try_to_define_name () print (i) #引用名字i之前, called the function
Before referring to the name I, obviously called the function, defined the name I, but still cannot find the name:
Traceback (most recent calls): File "scope_test.py", line <module> print (i) #引用名字i之前, called function Nameerror: Name ' I ' is not defined
Although name I is defined, it is defined in the local namespace corresponding to the local scope of the function, and according to the LEGB search rule, the local scope is not accessible in the global scope; Moreover, after the function call is finished, the namespace is destroyed.
The reference name is always related to the scope, so:
In Python, a name can be referenced in the appropriate scope only after it has been defined.
Then, when defining a name, you should pay attention to the scope of the name definition, so as not to be found when the definition requires access. Therefore, it is necessary to understand when Python will introduce a new scope. In general, the introduction of B,g two scopes is only e,l in scopes that cannot be manipulated by code and can be introduced through a statement. The syntax for introducing new scopes in Python is limited, and there are generally only two types:
The function definition introduces either the local scope or the enclosing scope; in essence, lambda and generator expressions are also functions that introduce new scopes.
The class definition is introduced into the local scope;
The list derivation introduces the local scope, legend says in Python2 the list derivation does not introduce a new scope
Some of the most confusing places for apes with other high-level language experiences:
If statement:
If True: i = 1print (i) # output:1, not Nameerror
The IF statement does not introduce a new scope, so the name binding statement I = 1 is in the same scope as print (i).
For statement:
For I in range (6): passprint (i) #output: 5 instead of Nameerror
The For statement also does not introduce a new scope, so the binding and rebinding of the name I is with print (i) in the same scope. This is a bit more than Python, so write code to avoid the name of the for loop and other names do not have the same name.
Import statement:
Def import_sys (): ' import sys module ' ' import Sysimport_sys () print (sys.path) # nameerror:name ' sys ' is not de Fined
This is a non-normal programmer's writing, the import statement in the function import_sys the name sys and the corresponding module binding, the SYS name is still defined in the local scope, with the above example there is no task difference. Always remember Python's name, object, this other programming language is not the same, but:
The second programming language that breaks the first programming language cognition is a good language that is worth learning.
3. Scope Application
3.1 Free variable readable and non-writable
I don't really want to use the word "variable" to describe a name, but the variable is a well-known, free variable in python:
If A variable is used in a code block and not defined there, it's a free variable.
If the code block where the reference occurs is not where it is defined, it is a free variable. A professional point is:
The name is not in the scope of the reference name, and the name is a free name.
Note: "Free name" is only the author yy, and has not been widely recognized.
We have learned the scope of the LEGB hierarchy and search for names sequentially. In search order, when a lower scope does not have a name to search for, a name that refers to a high-level scope exists, that is, a free name:
[Example 1]
Def low_scope (): print (s) s = ' upper scope ' low_scope ()
It is clear that the output of this code is upper scope.
[Example 2]
Def low_scope (): s = ' lower scope ' s = ' upper scope ' Low_scope () print (s)
Unfortunately, the final print statement did not print out lower scope as expected, but instead printed the upper scope.
A Special quirk of Python is that–if no global statement are in effect–assignments to names all go into the Innermos T scope.
One quirk of Python is that if you do not use the global statement, assignment statements for a name usually affect the inner scope.
That is, the assignment statement affects the local scope, the effect of the assignment statement is binding or rebinding, but in the namespace of the current local scope, there is no name s, so the assignment statement is used locally to define the name S, which does not conflict with s in the outer scope, because they belong to different namespaces.
In this way, the global scope's S is not re-bound, and the result is well explained.
When a mutable object is involved, the situation is different:
[Example 3]
Def low_scope (): l[0] = 2l = [1, 2]low_scope () print (L) # [2, 2]
Unfortunately, the final print statement did not follow the expected output [1, 2] but output [2, 2].
The experience of the previous example cannot be applied here, because the list as a mutable object, l[0] = 2 is not a rebinding of the name L, but a rebinding of the first element of L, so no new name is defined. As a result, the value of global work for the referenced object in L is updated successfully in the function.
Note that the following example is not the same as above:
[Example 4]
Def low_scope (): L = [2, 2]l = [1, 2]low_scope () print (L) # [1, 2]
We can interpret it using the method in Example 1 in this section.
In conclusion, it can be considered that:
Free variables are readable and not writable.
3.2 Global and nonlocal
There is always a need to break the rules:
In the lower scope, you need to rebind the high-level role domain name, i.e., by a free name.
The global statement and the nonlocal statement are then shipped.
GLOBAL_STMT:: = "global" identifier ("," identifier) *the Global statement is a declaration which holds for the entire Curr ENT code block. It means that the listed identifiers is to be interpreted as globals. It would is impossible to assign to a global variable without global, although free variables could refer to globals without Being declared global.
The Global statement is a declaration statement that applies to the current block of code. The identifiers listed are interpreted as global names. Although a free name can refer to global names without being declared global, it is not possible to bind global names without using the Global keyword.
NONLOCAL_STMT:: = "nonlocal" identifier ("," identifier) *the nonlocal statement causes the listed identifiers to refer Previously bound variables in the nearest enclosing scope excluding globals. This was important because the default behavior for binding are to search the local namespace first. The statement allows encapsulated code to rebind variables outside of the local scope besides the global (module) scope.
The nonlocal statement causes the name listed to point to the name of the binding in the nearest enclosing function, not the global name. The default binding behavior searches for local scopes first. The nonlocal statement makes it possible to rebind the names of outer function scopes in the inner function, even if the names of the same name exist in the global scope.
Classic examples of the official:
Def scope_test (): def do_local (): spam = ' local spam ' def do_nonlocal (): nonlocal spam # When the spam name is not present in the outer scope, nonlocal cannot define a spam = ' nonlocal spam ' # Free name Spam after nonlocal declaration, can do the re-binding operation, can be written. def do_global (): Global spam # Even if there is no definition of the name spam in the global scope, this statement can be defined in the global scope name spam spam = ' Global spam ' # The own variable spam after the global Declaration, can do the re-binding operation, can be written. spam = ' Test spam ' do_local () print ("After local assignment:", spam) # after local assignment:test SPAM
do_nonlocal () print ("After nonlocal assignment:", spam) # after nonlocal assignment:nonlocal spam do_ Global () print ("After global assignment:", spam) # After global assignment:nonlocal spamscope_test () print (' in Global scope: ", spam) # in global Scope:global spam
The author says no nonlocal evil:
Def nest_outter (): spam = ' outer ' def nest_inner (): nonlocal spam1 spam1 = ' inner ' nest_ Inner () print (spam) nest_outter ()
Output:
File "scope_test.py", line nonlocal spam1syntaxerror:no binding for nonlocal ' spam1 ' found
4. Some pits
The author was confident that he had a thorough understanding of the scope of Python, but a large pile of pits were too much to touch.
4.1 Pit 1-unboundlocalerror
def test (): print (i) i = 1i = 2test ()
Output:
Traceback (most recent call last): File "scope_test.py", line-in <module> test () file "scope_test.py", line , in test print (i) unboundlocalerror:local variable ' i ' referenced before assignment
In fact, it is understandable to ignore the statement I = 2 in the global scope.
Usually, the local scope references the local names of the (textually) current function.
Python has a unique local scope, and the interpreter executes to print (i), I do not have it in the local scope. When the interpreter tries to proceed with the definition of the name I, the interpreter will assume that the code was named before the definition, so it throws the exception. If the interpreter finishes explaining the entire function and does not find the name I, it will go up and down the search chain LEGB, and finally cannot find the thrown Nameerror exception.
4.2 Pit 2-local scope of the class
Class Test (object): i = 1 def test_print (self): print (i) T = Test () i = 2t.test_print ()
I'll ask everyone, what's this output?
Of course, the output is unexpectedly 2, especially those with other language experience will be more confused.
As highlighted above:
What is the life cycle of a function namespace? The invocation begins, returns, or ends abnormally, although the method called is in the example, but is essentially a function that invokes the class.
What is the scope of the class namespace? The class definition begins and the class finishes defining the end.
When the class definition starts, a new namespace that belongs to the class is created and used as a local scope. After the class is defined, the namespace is destroyed, and there is no direct way to access the I in the class (unless through indirect access: TEST.I).
The essence of a method invocation is a function call:
Class Test (object): i = 1 def test_print (self): print (i) T = Test () i = T.test_print () test.test_print (t) # Square How the method call was last converted to a function call
The function call begins with its scope and global scope having a subordinate relationship (L and G), the function I as a free name, and the last output 2.
Therefore, you cannot confuse the location of data members and function members in a class, always remember that two ways to access references in Python are:
Direct reference: Attempting to write names directly by name name, Python searches for names by searching LEGB scopes.
Indirect reference: Use Objname.attrname to refer to the name Attrname,python do not search scopes, go directly to the object to find properties.
4.3 Pit 3-list derivation local scope
A normal-list derivation:
A = 1b = [A + I for I in Range]]print (b) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Now put the list deduction into the class:
Class Test (object): a = 1 b = [A + I for I in Range] print (b) def Test (self): Pass
Output:
Traceback (most recent): File "scope_test.py", line, <module> class Test (object): File "Scope_te st.py ", line Max, in Test b = [A + I for I in Range]] File" scope_test.py ", line, in <listcomp> b = [a + I for I in range (Ten)]nameerror:name ' A ' is not defined
Output feedback name A is not defined.
As highlighted above, after the interpreter reads the class definition starting with class classname, the namespace is created as a local scope.
Statement A = 1, the name I is defined in this local scope
Statement B = [A + I for I in Rage (10)], the list deduction similarly creates a local scope. This scope does not have a subordinate relationship to the local scope defined by the class, so there is no way to directly access the name A.
There are only four scopes in Python: LEGB, because the local scope of the class definition and the list derivation are not nested function relationships, it does not constitute a enclosing scope relationship. Therefore, they are two independent local scopes and cannot be accessed from each other.
Since it is a two independent local scope, the above example is equivalent to:
def test1 (): i = 1def test2 (): print (i) test1 () test2 ()
It is obviously not feasible to expect to visit Test1 's name I in Test2.
"Recommended"
1. Python and, or, and and-or syntax summary
2. A detailed description of Python's scope five knowledge points
3. Detailed description of and and or actual usage in Python
4. Summary of 12 basic knowledge commonly used in Python programming