Namespaces are one honking great idea -- let's do more of those!
--The Zen of Python ("import this
")
The primary documentation for this is the Execution model section of the Python 3 reference and the Scopes and Namespaces section of the Classes tutorial. Wikipedia also has a useful summary. How lookup works gets into the deep, grungy details.
Python programs are constructed from code blocks: modules, function
bodies, and class definitions. Blocks are executed as a unit and
each block has its own namespace, a map of name → value bindings
accessible as attributes on the object where one exists (modules,
classes and class instances, but not stand-alone functions). In
CPython the namespace is stored as the __dict__
attribute on the
object but this is probably implementation-dependent.
There are four categories of namespace that are searched in 'LEGB' order to find the nearest in-scope binding:
- (L) The local namespace of currently executing function or class definition.
- (E) The namespaces of lexically enclosing functions or class
definitions.
locals()
returns the current function or class's namespace dictionary. - (G) The namespace of the current module, refered to as a
'Global' namespace. (Despite the name, it's a namespace local to
just that module.)
globals()
returns the current module object's namespace dictionary. (Usesys.modules[__name__]
to get the module itself. It has an attribute__dict__
, which symbol is not in the global namespace, containing the global namespace.) - (B) The namespace of the
builtins
module. This is the outermost scope and is accessible from everywhere. The CPython implementation also makes this available via the__builtins__
global set in every module namespace.
Two namespaces are created when the interpreter starts: the builtin
namespace on the builtin
module and a 'global' namespace on the
__main__
module in which the top-level code runs. (Well, typically
more will be created for other modules that are loaded at startup
time.)
Bindings are created with any of the following statements:
- Assignment:
x = ...
. global x
andnonlocal x
, which bind x to an enclosing block's x and the current module's x, respectively. In both cases you may change the binding and that will be reflected in the encloser's binding.- Various forms of the
import
statement. def x():
class x:
These all create a binding that applies to the entire block, both before and after the statement creating the binding, though the variable will be unbound before the statement that creates the binding. Thus,
x = 1
def f():
print('x=%s' % x)
x = 3
f()
⇒ UnboundLocalError: local variable 'x' referenced before assignment
Class definitions are executed to build the class; they have their own
namespace (for class variables, including functions) while executing
and the bindings become available as attributes on the class object.
Instance variables are referenced explicitly as attributes the first
(self
) parameter passed to instance functions.
class C:
c = 1
@staticmethod
def s(cls): pass
def f(self):
self.i = 2
o = C()
C.c # class variable ==> 1
C.s # class method ==> <function __main__.C.s>
C.f # instance method ==> <function __main__.C.f>
o.f(); o.i # instance variable ==> 2
Define base classes for inheritance using an argument list after the class name. Each argument must evaluate to a class object. When a requested attribute is not found in the class itself, each base class is searched in turn.
from collections.abc import *
class C(Sized, Iterator):
def __len__(self): # Abstract from Sized; must be implemented.
return 0
def __next__(self): # Abstract from Iterator; must be implemented.
raise StopIteration()
c = C()
isinstance(Sized, c) # ⇒ True
isinstance(Iterator, c) # ⇒ True
iter(c) # Calls __iter__() provided by Iterator
See Metaclasses.
+-object
+-Exception
+-BaseException
+-NameError
+-UnboundLocalError