[Edu-sig] More on teaching about namespaces

kirby urner kirby.urner at gmail.com
Wed Sep 13 22:15:52 CEST 2006


> Go crazy, play, explore.  We'll start up with the formal talk in about
> 15 minutes, and answer any questions.  Bathroom is down the hall to
> your right.
>
> Kirby
>

Now, reviewing what we did just before break:

>>> a = [1,2,3,4]
>>> b = iter(a)
>>> id(a)
23472728
>>> id(b)
23397744
>>> type(a)
<type 'list'>
>>> type(b)
<type 'listiterator'>

I'm showing that feeding a list to the builtin iter, gets you back a
new type of object, and hence a *different* object.

I know they're different because their ids are different.

But what if I feed b, already a listiterator, to iter *again*?

>>> c=iter(b)
>>> c
<listiterator object at 0x01650570>
>>> id(c)
23397744
>>> hex(23397744)
'0x1650570'
>>> b
<listiterator object at 0x01650570>
>>> b is c
True

You see there's some logic here.

Whereas iter ate 'a' to return a different 'b', when it eats 'b' it
just returns the same object.

Yes, I've referenced said object with the letter 'c', using the
assignment operator (=), but "under the hood", b and c have the same
id, expressed in decimal, but from the hex conversion you see there's
a match.

Just to confirm, I use the "is" keyword.

What do I mean by keyword?

A keyword is different from a builtin.

By default, IDLE will colorize the latter purple, the former orange.

Let's look at keywords for a minute, and in doing so, we'll discover
this powerful keyword used to augment our namespace with additional
namespaces: import...

>>> help('keyword')
Help on module keyword:

NAME
    keyword - Keywords (from "graminit.c")

FILE
    d:\python25\lib\keyword.py

DESCRIPTION
    This file is automatically generated; please don't muck it up!

    To update the symbols in this file, 'cd' to the top directory of
    the python source tree after building the interpreter and run:

        python Lib/keyword.py

FUNCTIONS
    iskeyword = __contains__(...)
        x.__contains__(y) <==> y in x.

DATA
    __all__ = ['iskeyword', 'kwlist']
    kwlist = ['and', 'as', 'assert', 'break', 'class', 'continue', 'def', ...


>>> import keyword

>>> keyword.iskeyword('is')
True

>>> keyword.kwlist
['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del',
'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global',
'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print',
'raise', 'return', 'try', 'while', 'with', 'yield']

Now that's pretty short for a language's list of key words.  Many
languages have more.  How many is this?

>>> len(keyword.kwlist)
31

Just 31, compared to how many builtins (pause to let people try the
len builtin -- drop a few hints as they flounder):

>>> len(dir(__builtins__))
134

Yeah, woah, big difference.  Lots more builtins.

Let's check our current namespace again:

>>> dir()
['__builtins__', '__doc__', '__name__', 'a', 'b', 'c', 'keyword']

Aha -- those letter references we created, are still here with us.
And keyword, a module, has joined __builtins__.

We can start purging the namespace if we feel it's too crowded.
Restart IDLE, or selectively use del:

>>> del a
>>> del b

Note:  even though be is gone, c still references the object in
memory.  That object won't be garbage collected until no name
references it any more.

>>> c
<listiterator object at 0x01650570>
>>> del c

What if we try deleting __builtins__?

>>> del __builtins__
>>> dir()
['__builtins__', '__doc__', '__name__', 'keyword']

Didn't work.  Nothing happens.  But the keyword namespace is easy to get rid of:

>>> del keyword
>>> dir()
['__builtins__', '__doc__', '__name__']

Interesting.

Now here's some interesting stuff:

>>> dir(__doc__)
['__class__', '__delattr__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__str__']

>>> type(__doc__)
<type 'NoneType'>

>>> type(None)
<type 'NoneType'>

>>> dir(None)
['__class__', '__delattr__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__str__']

__doc__ references nothing at this point and so its type (the type of
object it references) is None.

There's just this one None in memory:

>>> id(None)
505251592
>>> id(__doc__)
505251592

OK, we've reached the end of our first session.  Next time we meet,
we'll import visual and start making stuff happen on top of OpenGL,
using the VPython package.  You'll start to appreciate what Python
will really do for you.

If you don't remember Vectors from high school, don't worry.  They're
pretty easy, especially with VPython at your elbow.

But first, here's a puzzle:

>>> 134 < 31
False

The '<' operator behaves as you'd expect, but that operator nowhere
appeared in the list of builtins or as a keyword.  Why is it
operational, if it's not in the namespace.

Here's a hint.  Go dir(134) or dir(31).

More next time.

Kirby


More information about the Edu-sig mailing list