[Python-ideas] Unify global and nonlocal

Steven D'Aprano steve at pearwood.info
Tue Feb 4 02:23:52 CET 2014


On Mon, Feb 03, 2014 at 08:40:08PM +0000, Amber Yust wrote:
> global and nonlocal are different specifically because they do different
> things. Yes, there is a reason why nonlocal stops at the first scope up -
> because that's what it exists to do.

+1

"There should be one obvious way to do it" doesn't apply here, because 
there is no *it*, there is *them*. Two distinct things to do, rather 
than one:

- enable writing to the top-level global namespace;

- enable writing to some enclosing non-local scope.

I say *some enclosing* scope rather than *the enclosing scope* because 
you can have more than one. The nonlocal keyword enables writing to the 
nearest enclosing scope which already contains the given name, not 
necessarily the closest enclosing scope:


py> def outer():
...     a = "outer"
...     def inner():
...             def innermost():
...                     nonlocal a
...                     a = "modified"
...             innermost()
...     print("Before:", a)
...     inner()
...     print("After:", a)
...
py> outer()
Before: outer
After: modified


The global namespace is special, and special enough to justify being 
handled specially. Of course, it is possible to generalise the idea that 
globals are "just" a case of lexical scoping, and there is some truth to 
that. But it's an over-generalisation, a bit like deciding that since 
the built-in len() function is just a many-to-one transformation of 
arbitrary sequences to integers, it belongs as a codec:

import codecs
length_of_list = codecs.encode(my_list, "len")


In the case of globals and non-locals:

* Non-locals always have an enclosing function, globals do not.

* Non-locals and globals are typically used for different purposes, 
  by users at different levels of expertise. Writing to a non-local 
  scope using the nonlocal keyword tends to be done only by advanced 
  users for advanced purposes; writing to global variables using the 
  global keyword tends to be done only by beginners who haven't yet 
  learned that global variables are considered harmful.

* A corrolary of the above is that it is difficult to think of any 
  use-cases where you don't know at edit-time whether you intend to 
  write to a variable in the global scope or a non-local scope. I can't 
  think of any case where I wouldn't know whether to declare something 
  global or nonlocal ahead of time, so there's no advantage to having a 
  single keyword handle both cases.



-- 
Steven


More information about the Python-ideas mailing list