Short description of the scoping rules?
Actually, a concise rule for Python Scope resolution, from Learning Python, 3rd. Ed.. (These rules are specific to variable names, not attributes. If you reference it without a period, these rules apply.)
Local — Names assigned in any way within a function (
lambda), and not declared global in that function
Enclosing-function — Names assigned in the local scope of any and all statically enclosing functions (
lambda), from inner to outer
Global (module) — Names assigned at the top-level of a module file, or by executing a
globalstatement in a
defwithin the file
Built-in (Python) — Names preassigned in the built-in names module:
So, in the case of
code1class Foo: code2 def spam(): code3 for code4: code5 x()
for loop does not have its own namespace. In LEGB order, the scopes would be
- L: Local in
- E: Any enclosing functions (if the whole example were in another
- G: Were there any
xdeclared globally in the module (in
- B: Any builtin
Essentially, the only thing in Python that introduces a new scope is a function definition. Classes are a bit of a special case in that anything defined directly in the body is placed in the class's namespace, but they are not directly accessible from within the methods (or nested classes) they contain.
In your example there are only 3 scopes where x will be searched in:
spam's scope - containing everything defined in code3 and code5 (as well as code4, your loop variable)
The global scope - containing everything defined in code1, as well as Foo (and whatever changes after it)
The builtins namespace. A bit of a special case - this contains the various Python builtin functions and types such as len() and str(). Generally this shouldn't be modified by any user code, so expect it to contain the standard functions and nothing else.
More scopes only appear when you introduce a nested function (or lambda) into the picture.These will behave pretty much as you'd expect however. The nested function can access everything in the local scope, as well as anything in the enclosing function's scope. eg.
def foo(): x=4 def bar(): print x # Accesses x from foo's scope bar() # Prints 4 x=5 bar() # Prints 5
Variables in scopes other than the local function's variables can be accessed, but can't be rebound to new parameters without further syntax. Instead, assignment will create a new local variable instead of affecting the variable in the parent scope. For example:
global_var1 = global_var2 = 1def func(): # This is OK: It's just accessing, not rebinding global_var1.append(4) # This won't affect global_var2. Instead it creates a new variable global_var2 = 2 local1 = 4 def embedded_func(): # Again, this doen't affect func's local1 variable. It creates a # new local variable also called local1 instead. local1 = 5 print local1 embedded_func() # Prints 5 print local1 # Prints 4
In order to actually modify the bindings of global variables from within a function scope, you need to specify that the variable is global with the global keyword. Eg:
global_var = 4def change_global(): global global_var global_var = global_var + 1
Currently there is no way to do the same for variables in enclosing function scopes, but Python 3 introduces a new keyword, "
nonlocal" which will act in a similar way to global, but for nested function scopes.
There was no thorough answer concerning Python3 time, so I made an answer here. Most of what is described here is detailed in the 4.2.2 Resolution of names of the Python 3 documentation.
As provided in other answers, there are 4 basic scopes, the LEGB, for Local, Enclosing, Global and Builtin. In addition to those, there is a special scope, the class body, which does not comprise an enclosing scope for methods defined within the class; any assignments within the class body make the variable from there on be bound in the class body.
Especially, no block statement, besides
class, create a variable scope. In Python 2 a list comprehension does not create a variable scope, however in Python 3 the loop variable within list comprehensions is created in a new scope.
To demonstrate the peculiarities of the class body
x = 0class X(object): y = x x = x + 1 # x is now a variable z = x def method(self): print(self.x) # -> 1 print(x) # -> 0, the global x print(y) # -> NameError: global name 'y' is not definedinst = X()print(inst.x, inst.y, inst.z, x) # -> (1, 0, 1, 0)
Thus unlike in function body, you can reassign the variable to the same name in class body, to get a class variable with the same name; further lookups on this name resolveto the class variable instead.
One of the greater surprises to many newcomers to Python is that a
for loop does not create a variable scope. In Python 2 the list comprehensions do not create a scope either (while generators and dict comprehensions do!) Instead they leak the value in the function or the global scope:
for i in range(5) ] i4[ i
The comprehensions can be used as a cunning (or awful if you will) way to make modifiable variables within lambda expressions in Python 2 - a lambda expression does create a variable scope, like the
def statement would, but within lambda no statements are allowed. Assignment being a statement in Python means that no variable assignments in lambda are allowed, but a list comprehension is an expression...
This behaviour has been fixed in Python 3 - no comprehension expressions or generators leak variables.
The global really means the module scope; the main python module is the
__main__; all imported modules are accessible through the
sys.modules variable; to get access to
__main__ one can use
import __main__; it is perfectly acceptable to access and assign attributes there; they will show up as variables in the global scope of the main module.
If a name is ever assigned to in the current scope (except in the class scope), it will be considered belonging to that scope, otherwise it will be considered to belonging to any enclosing scope that assigns to the variable (it might not be assigned yet, or not at all), or finally the global scope. If the variable is considered local, but it is not set yet, or has been deleted, reading the variable value will result in
UnboundLocalError, which is a subclass of
x = 5def foobar(): print(x) # causes UnboundLocalError! x += 1 # because assignment here makes x a local variable within the function# call the functionfoobar()
The scope can declare that it explicitly wants to modify the global (module scope) variable, with the global keyword:
x = 5def foobar(): global x print(x) x += 1foobar() # -> 5print(x) # -> 6
This also is possible even if it was shadowed in enclosing scope:
x = 5y = 13def make_closure(): x = 42 y = 911 def func(): global x # sees the global value print(x, y) x += 1 return funcfunc = make_closure()func() # -> 5 911print(x, y) # -> 6 13
In python 2 there is no easy way to modify the value in the enclosing scope; usually this is simulated by having a mutable value, such as a list with length of 1:
def make_closure(): value =  def get_next_value(): value += 1 return value return get_next_valueget_next = make_closure()print(get_next()) # -> 1print(get_next()) # -> 2
However in python 3, the
nonlocal comes to rescue:
def make_closure(): value = 0 def get_next_value(): nonlocal value value += 1 return value return get_next_valueget_next = make_closure() # identical behavior to the previous example.
nonlocal documentation says that
Names listed in a nonlocal statement, unlike those listed in a global statement, must refer to pre-existing bindings in an enclosing scope (the scope in which a new binding should be created cannot be determined unambiguously).
nonlocal always refers to the innermost outer non-global scope where the name has been bound (i.e. assigned to, including used as the
for target variable, in the
with clause, or as a function parameter).
Any variable that is not deemed to be local to the current scope, or any enclosing scope, is a global variable. A global name is looked up in the module global dictionary; if not found, the global is then looked up from the builtins module; the name of the module was changed from python 2 to python 3; in python 2 it was
__builtin__ and in python 3 it is now called
builtins. If you assign to an attribute of builtins module, it will be visible thereafter to any module as a readable global variable, unless that module shadows them with its own global variable with the same name.
Reading the builtin module can also be useful; suppose that you want the python 3 style print function in some parts of file, but other parts of file still use the
import __builtin__print3 = __builtin__.__dict__['print']
from __future__ import print_function actually does not import the