Document nonlocal statement. Written for GHOP by "Canadabear".

This commit is contained in:
Georg Brandl 2007-12-04 18:11:03 +00:00
parent 52ca6cc9c8
commit c5d98b4eee
2 changed files with 85 additions and 7 deletions

View File

@ -765,12 +765,42 @@ The :keyword:`nonlocal` statement
.. productionlist::
nonlocal_stmt: "nonlocal" `identifier` ("," `identifier`)*
XXX: To be documented.
.. XXX add when implemented
: ["=" (`target_list` "=")+ `expression_list`]
: | "nonlocal" `identifier` `augop` `expression_list`
The :keyword:`nonlocal` statement causes the listed identifiers to refer to
previously bound variables in the nearest enclosing scope. This is important
because the default behavior for binding is to search the local namespace
first. The statement allows encapsulated code to rebind variables outside of
the local scope besides the global (module) scope.
.. note::
The outer scope for :keyword:`nonlocal` statements cannot be the module
scope.
.. XXX not implemented
The :keyword:`nonlocal` statement may prepend an assignment or augmented
assignment, but not an expression.
Names listed in a :keyword:`nonlocal` statement, unlike to those listed in a
:keyword:`global` statement, must refer to pre-existing bindings in an
enclosing scope (the scope in which a new binding should be created cannot
be determined unambiguously).
Names listed in a :keyword:`nonlocal` statement must not collide with
pre-existing bindings in the local scope.
.. seealso::
:pep:`3104` - Access to Names in Outer Scopes
The specification for the :keyword:`nonlocal` statement.
.. rubric:: Footnotes
.. [#] It may occur within an :keyword:`except` or :keyword:`else` clause. The
restriction on occurring in the :keyword:`try` clause is implementor's laziness
and will eventually be lifted.
restriction on occurring in the :keyword:`try` clause is implementor's
laziness and will eventually be lifted.

View File

@ -137,14 +137,62 @@ language definition is evolving towards static name resolution, at "compile"
time, so don't rely on dynamic name resolution! (In fact, local variables are
already determined statically.)
A special quirk of Python is that assignments always go into the innermost
A special quirk of Python is that assignments normally go into the innermost
scope. Assignments do not copy data --- they just bind names to objects. The
same is true for deletions: the statement ``del x`` removes the binding of ``x``
from the namespace referenced by the local scope. In fact, all operations that
introduce new names use the local scope: in particular, import statements and
function definitions bind the module or function name in the local scope. (The
:keyword:`global` statement can be used to indicate that particular variables
live in the global scope.)
function definitions bind the module or function name in the local scope.
The :keyword:`global` statement can be used to indicate that particular
variables live in the global scope and should be rebound there; the
:keyword:`nonlocal` statement indicates that particular variables live in
an enclosing scope and should be rebound there.
.. _tut-scopeexample:
Scopes and Namespaces Example
-----------------------------
This is an example demonstrating how to reference the different scopes and
namespaces, and how :keyword:`global` and :keyword:`nonlocal` affect variable
binding::
def scope_test():
def do_local():
spam = "local spam"
def do_nonlocal():
nonlocal spam
spam = "nonlocal spam"
def do_global():
global spam
spam = "global spam"
spam = "test spam"
do_local()
print("After local assignment:", spam)
do_nonlocal()
print("After nonlocal assignment:", spam)
do_global()
print("After global assignment:", spam)
scope_test()
print("In global scope:", spam)
The output of the example code is::
After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam
Note how the *local* assignment (which is default) didn't change *scope_test*\'s
binding of *spam*. The :keyword:`nonlocal` assignment changed *scope_test*\'s
binding of *spam*, and the :keyword:`global` assignment changed the module-level
binding.
You can also see that there was no previous binding for *spam* before the
:keyword:`global` assignment.
.. _tut-firstclasses: