[Tutor] scope of a global dictionary?

Marilyn Davis marilyn at deliberate.com
Fri Feb 6 19:21:10 EST 2004


On Fri, 6 Feb 2004, Karl Pflästerer wrote:

> On  6 Feb 2004, Marilyn Davis <- marilyn at deliberate.com wrote:
> 
> > My understanding is that a global variable can be accessed, but not
> > altered in a function's code block, unless the global declaration is
> > used:
> 
> That's not entirely true.
> 
> > x = 3
> > def f():
> >     print x       <-  is ok
> 
> No binding of a name
> 
> > def g():
> >     x += 1        <-  not ok
> 
> Here x gets bound to x+1.
> 
> > def h():
> >     global x
> >     x *= 2        <-  ok again
> 
> Here you declared x global.  That short circuits the name resolving.
> 
> 
> > But I wrote this little dictionary example and it doesn't need the
> > global declaration to add new entries to the dictionary.
> 
> Yes and no :-)
> 
> >         dict[word.lower()] = meaning
> 
> Here again; you don't bind the name dict to a new value.
> 
> 
> A small example to make it clearer:
> >>> lst = [1]
> >>> def f (): return lst
> ... 
> >>> def g():
> ...     lst.append(1)
> ...     return f()
> ... 
> >>> def h(): lst = lst + lst
> ... 
> >>> f()
> [1]
> >>> g()
> [1, 1]
> >>> h()
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "<stdin>", line 1, in h
> UnboundLocalError: local variable 'lst' referenced before assignment
> >>> 
> 
> 
> So g() caused no problems but could change the value of lst.  What is
> the difference to h()?  In h() we made an assignment operation and
> assignment statements *bind* names.  Now `lst' was the `lst' in the
> local function scope and no longer an arbitrary name which could be
> searched in the surrounding environment (or __builtin__).
> 
> That whole issue is not trivial; if you want to know more about it read

No.  Your example is clear and excellent.  I get it now.

> e.g. Pep 227 (which describes the lexical (statical) scoping rules and
> explains also these subtilities; furthermore you could read in the
> Python reference about `Naming and Binding' (in the section `Execution
> model').  On example from the Pep which shows a problem which can arise 
> 
> ,----[ pep 227 ]
> | An example from Tim Peters demonstrates the potential pitfalls of
> |     nested scopes in the absence of declarations:
> | 
> |     i = 6
> |     def f(x):
> |         def g():
> |             print i
> |         # ...
> |         # skip to the next page
> |         # ...
> |         for i in x:  # ah, i *is* local to f, so this is what g sees
> |             pass
> |         g()
> | 
> |     The call to g() will refer to the variable i bound in f() by the for
> |     loop.  If g() is called before the loop is executed, a NameError will
> |     be raised.
> `----
> 
> Since `i' gets bound in the function declaration (the for loop bounds
> also) a similar problem like yours happens.

Woah.  Interesting.

> 
> HTH

HAWL (Helps A Whole Lot!)

Marilyn

> 
>    Karl
> 

-- 




More information about the Tutor mailing list