[Tutor] Question about namespace

Magnus Lycka magnus@thinkware.se
Tue Mar 25 11:00:01 2003


At Mon, 24 Mar 2003 17:43:02 +0000, Andy wrote:
>Guido van Rossum defines namespace as a "mapping from names to objects"
>(Tutorial - Python 2.2.2 :S.9.2 p 54). Would I be correct to think of this
>as - in Linux-speak - making a symlink that creates a symlink (or
>'shortcut'/link) between the local reference (the link) and the module or
>function itself (the 'target') which 'resides' elsewhere (i.e. has a
>global scope)?

Almost. It's not a symbolic link (ln -s), it's a *hard* link!

$ echo "Graham" > brian # Make a file containing "Graham" and name it brian
$ ln brian arthur       # Name it arthur as well
$ rm brian              # Remove the name brian
$ cat arthur            # But the name arthur still refers to the file
Graham
$ rm arthur             # Let the filesystem use that space for something 
else now

You see? As long as there is one reference to the object, it
will remain. This is analogous to:

 >>> brian = "Graham"  # Make a string "Graham" and let brian refer to it
 >>> arthur = brian    # Let arthur refer to the same string as brian
 >>> del brian         # Remove the name brian
 >>> print arthur      # The name arthur still refers to "Graham" though
Graham
 >>> del arthur        # We're done, remove the last reference ad let it
                       # be "garbage collected"

All variable names refer equally much to the object, and as
long as there is at least one remaining reference, the object
will live on.

If you do "ln -s" instead of "ln", or if you make one of those
crippled Windows shortcuts, you add a level of indirection.

$ echo "Graham" > brian
$ ln -s brian arthur      # Let arthur rely on brian to provide something
$ rm brian
$ cat arthur              # Oops, brian's gone, we're lost! :(
cat: arthur: No such file or directory

With only soft links, there is (as in LeGuin's Earthsea trilogy)
one true name for everything. All other names are just aliases
for the one true name. With hard links, as in Python, all names
are equal. Which name came first is of no relevance.

There you are! Python variables and objects aren't like Earthsea!

You can't make such nasty things in Python. There is no
way (that I know of) you can get a reference to a variable.
You always work with references to objects, whether you access
them as variables, attributes, members in a collection or
whatever.

This type of indirection is commonly used in other languages
such as C and derivates though, and they cause an enless
amount of bugs...

A variable in Python is only a named reference to an object.

A variable in for instance C is a named location in memory
that can house a particular kind of value.

For instance, if you do this in C:

int a; /* Reserve name in memory for an integer */
a = 5; /* Place the integer value 5 in this place */
a = 7; /* Replace 5 with 7 at that location in memory */

it's not at all the same as in Python:

a = 5 # Place integer value 5 on the heap, make a point to it.
a = 7 # Place integer value 7 on the heap, make a point to
       # that instead. If there is no other reference to 5,
       # it will be cleaned by the GC.

The python way is vastly superior. The C way basically breaks
down as soon as you try to store something more complex than
an integer. You get a mix of directly and indirectly (in one
or more steps) refered values, leading to confusing rules
about pointers and references and pointers to pointers to
pointers. People with many years of experience still have to
think very hard to get it right, and need to test such
trivialities as accessing a variable in a complex structure
very carefully to get it right. Don't laugh, I've been there.
It's no fun! (It's always uplifting to get something difficult
right in the end, but I'd rather spend my brain cells on hard
problems with good tools than on trivial problems with difficult
tools. Viva Python!)

In Python you need to understand the difference between
variables/names and the objects/values the refer to, and
you need to understand the difference between mutable and
immutable objects. Then the concept works for all kinds of
objects, with a single and simple access method. Heck, in
"Programming Perl" they spend page after page explaining
about all the mistakes you can do in dereferencing variables.

That means that if you manage to do the eqivalent to the
following code in Perl, you are involved in deep magic. It's
a bit like getting a black belt in karate to be able to do
such a thing without getting something like ARRAY(0x8101dc0)
or just nothing printed at the first three or four attempts.

a = 5
b = (a,)
c = [b]
print c[0][0]
5

If you understand a python dictionary, you should also understand
namespaces, since they *are* dictionaries.

 >>> x = 1
 >>> y = "hello"
 >>> def f(a, b):
...     print "locals=",locals()
...     print "globals=",globals()
...
 >>> f(x,y)
locals= {'a': 1, 'b': 'hello'}
globals= {'y': 'hello', 'x': 1, 'f': <function f at 0x8157394>,
'__builtins__': <module '__builtin__' (built-in)>,
'__name__': '__main__', '__doc__': None}

You see? They are just dictionaries, and dictionaries
are (as other collections) just a heap of references. There
is only one object containing 1, and one containing "hello".
Nothing is copied, the dicts / namespaces share references.

You can verify that with the id() function.

 >>> y = "hello"
 >>> id(y)
135614264
 >>> def f(object):
...     print id(object)
...
 >>> f(y)
135614264

You see! global 'y' and local 'object' refer to the same string.


-- 
Magnus Lycka, Thinkware AB
Alvans vag 99, SE-907 50 UMEA, SWEDEN
phone: int+46 70 582 80 65, fax: int+46 70 612 80 65
http://www.thinkware.se/  mailto:magnus@thinkware.se