Incomplete draft: Namespaces

Aahz aahz at pythoncraft.com
Sat Apr 6 17:07:08 EST 2002


I've been wrestling with the way namespaces really work, and I've been
discussing it a bit on python-dev.  I'm moving the discussion here to
get some broader viewpoints.  Here's an incomplete draft of what I've
got so far:

In Python, everything is an object: basic data types, classes, class
instances, functions, modules, and so on.  Objects are accessed through
bindings; a binding is a reference to an object, but the reference is
always implicit (unlike pointers).  Targets contain bindings.  Each time
an object gets bound to a target, the object's refcount gets increased.

Targets can be accessed through names or the __getitem__ / __setitem__
protocol.  A name is primary if it exists in execution scope.  A name is
an attribute if it is accessed via dot notation (or the __getattr__ /
__setattr__ protocol -- this gets a bit messy with new-style classes, so
we'll ignore that complication for now).  Computed bindings are accessed
through the __getitem__ / __setitem__ protocol.  There are also implicit
targets, such as the return statement.

A binding can refer to any Python object.  Multiple bindings can refer
to the same object.  Rebinding a target does not affect the original
object unless the original object's refcount goes to zero (and the
object gets automatically deleted).

A namespace is a collection of names that all exist within the same
execution scope or object.

The three execution scopes are function local (hereafter referred to as
local), module global (hereafter referred to as global), and builtin
scope.  Local scope exists any time Python's instruction pointer is
inside a function/method.  Global scope refers to the currently
executing module; explicitly accessing a function in another module
through attributes changes the current module:

    from M import f
    f()                 # f()'s global scope is the current module
    import M
    M.f()               # f()'s global scope is now the module M

Builtins are the same across all modules.  (It's possible to break this
explicitly through namespace games, but it's always true absent any
tricks.)

XXX Execution vs. object namespace

XXX Namespace lookups

Python only does indirect object lookups when retrieving an object
through a binding, not when creating bindings.  In other words

    a = 1
    def f():
        print a
    f()

will print 1, but

    def f():
        a = 1
    f()
    print a

generates a NameError.  In similar fashion

    class A:
        x = 1

    class B(A):
        pass

    B.y = 2
    print B.x

sets up a situation where B.x will look up in A's namespace to retrieve
x, but y goes into B's namespace.
-- 
Aahz (aahz at pythoncraft.com)           <*>         http://www.pythoncraft.com/

"There are times when effort is important and necessary, but this should
not be taken as any kind of moral imperative."  --jdecker



More information about the Python-list mailing list