Guilty secret: globals baffle me

Bengt Richter bokr at oz.net
Wed Nov 6 12:21:46 EST 2002


On Wed, 06 Nov 2002 14:53:56 GMT, Alex Martelli <aleax at aleax.it> wrote:

>Edward K. Ream wrote:
>   ...
>> 1. How many globals are there?  Is there just one, or does each module
>> define its own?
>
>The latter.  Each module has its own globals-dictionary.
>
>
>> 2. It seems that:
>> 
>> global foo
>> foo = x
>> ...
>> global
>> print foo
>> 
>> only works if the two parts are within the same module, so I think maybe
>> globals() returns module specific stuff, but then why call it globals?
>
>It seems that you haven't noticed the existence of functions (and
>their namespaces, particularly their crucial local namespace).
>
>The global statement only makes sense inside a function: it tells the
>Python compiler that certain names, that the function binds, rebinds
>or unbinds, are NOT (as is the normal case) local to the function, but
>rather refer to names in the module's globals-dictionary.
>
>Outside of any function, all names refer to the module's globals-
>dictionary, therefore the global statement is redundant -- useless,
>although technically innocuous.
>
>Given that names that only exist within a function are commonly
>called "local names" or "local variables" of that function, how
>else would you call names that AREN'T local, but rather global
>to all functions within the module?  Calling them "module names"
>would IMHO be far more confusing than calling them "global
>names" -- I think of module names as the names of modules; and
>the local/global distinction would become quite confused.
>
I agree. But BTW, don't forget in-between variables such as x in

 >>> def foo():
 ...     x=1
 ...     def bar():
 ...         print x
 ...     bar()
 ...     x=2
 ...     bar()
 ...
 >>> foo()
 1
 2

which isn't local to bar but isn't global either.

I have an uncomfortable feeling there is unfinished
business in the way names in nested scopes and otherwise
related namespaces work. The global/local dichotomy doesn't
fully express the possibilities any more. IMO it would be nice
to have full access to accessible namespaces without magically
determined access mode restrictions based on full-function lookahead.

I.e., we have a de facto hierarchy of name spaces defined by the
ability to nest functions. Why not have an access mechanism that
allows rebinding as desired? E.g., you could let locals take a depth argument,
so locals() is equivalent to locals(0), and locals(1) is the enclosing
name space, so locals(1)['x'] = 3 in bar above would rebind the x local to foo.

For notational convenience, you could make locals an object with a __getitem__ that
would return the name space as an object with attributes, so you could write
locals[1].x = 3 instead. Globals would be at the end of the list at locals[-1].

In conjuction with this,  I wonder if the PostScript way
of pushing and popping dictionaries onto/from a stack of
dictionaries has something that could be used by python.
Temporarily getting unqualified-name access to a chosen
namespace shadowing others by being on top seems like
a useful thing. Sort of like entering the local namespace
of a function without leaving the calling code context.

Thus pushing a dictionary would make it temporarily local[0]
and the previous local[0] would be local[1], so you could
still get at it explicitly if a name was shadowed and/or you
wanted to rebind there.

Lots of things would become possible. You could push a reference
to another module's global space temporarily, for unqualified name
access, or you could do it with kwargs, meaning just a reference push
instead of the update trick, and many other possibilities.

push_dir(local(1)) would give you transparent access to the enclosing
scope for read/rebind as if it were your own local space.

push_dir(vars(obj)) would let you write x = 1 and have the effect of obj.x = 1.
pop_dir() would revert to the previous unqualified name space.

Regards,
Bengt Richter



More information about the Python-list mailing list