[Python-Dev] closure semantics

Guido van Rossum guido at python.org
Tue Oct 21 19:40:34 EDT 2003


> Actually, I would rather like to DO AWAY with the anomalous 'global'
> statement and its weird anomalies such as:
> 
> x = 23
> 
> def f1(u):
>     if u:
>         global x
>     x = 45
> 
> def f2():
>     if 0:
>         global x
>     x = 45
> 
> print x
> f2()
> print x
> f1(0)
> print x
> 
> "if u:" when u is 0, and "if 0:", should have the same effect to avoid
> violating the least-astonishment rule -- but when the if's body has
> a global in it, they don't.  Eeek.

Eek.  Global statement inside flow control should be deprecated, not
abused to show that global is evil. :-)

> Plus. EVERY newbie makes the mistake of taking "global" to mean
> "for ALL modules" rather than "for THIS module",

Only if they've been exposed to languages that have such globals.

> uselessly using global in toplevel,

Which the parser should reject.

> etc.  It's a wart and I'd rather work to remove it than to expand
> it, even though I _would_ like rebindable outers.
> 
> I'd rather have a special name that means "this module" available
> for import (yes, I can do that with an import hook today).  Say that
> __this_module__ was deemed acceptable for this.  Then,
>     import __this_module__
>     __this_module__.x = 23
> lets me rebind the global-to-this-module variable x without 'global'
> and its various ills.  Yeah, the name isn't _too_ cool.  But I like the
> idea, and when I bounced it experimentally in c.l.py a couple weeks
> ago the reaction was mildly positive and without flames.  Making
> globals a TAD less handy to rebind from within a function would
> not be exactly bad, either.  (Of course 'global' would stay until 3.0
> at least, but having an alternative I could explain it as obsolescent:-).

I think it's not unreasonable to want to replace global with attribute
assignment of *something*.  I don't think that "something" should have
to be imported before you can use it; I don't even think it deserves
to have leading and trailing double underscores.

Walter suggested 'global.x = 23' which looks reasonable; unfortunately
my parser can't do this without removing the existing global statement
from the Grammar: after seeing the token 'global' it must be able to
make a decision about whether to expand this to a global statement or
an assignment without peeking ahead, and that's impossible.

> Extending this idea (perhaps overstretching it), some other name
> "special for import" might indicate outer scopes.  Though reserving
> the whole family of names __outer_<name>__ is probably overdoing
> it... plus, the object thus 'imported' would not be a module and would
> raise errors if you tried setattr'ing in it a name that's NOT a local
> variable of <name> (the import itself would fail if you were not lexically
> nested inside a function called <name>).  Thus this would allow
> *re-binding* existing local outer names but not *adding* new ones,
> which feels just fine to me (but maybe not to all).
> 
> OK, this is 1/4-baked for the closure issue.  BUT -- I'd STILL love
> to gradually ease 'global' out, think the "import __this_module__"
> idea is 3/4-baked (lacks a good special name...), and would hate
> to see 'global' gain a new lease of life for sophisticated uses...;-)

If we removed global from the language, how would you spell assignment
to a variable in an outer function scope?  Remember, you can *not* use
'outer.x' because that already refers to a function attribute.

--Guido van Rossum (home page: http://www.python.org/~guido/)



More information about the Python-Dev mailing list