[Python-checkins] r76271 - in python/branches/release31-maint: Doc/faq/programming.rst

r.david.murray python-checkins at python.org
Sat Nov 14 23:24:15 CET 2009


Author: r.david.murray
Date: Sat Nov 14 23:24:15 2009
New Revision: 76271

Log:
Merged revisions 76270 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/branches/py3k

................
  r76270 | r.david.murray | 2009-11-14 17:21:32 -0500 (Sat, 14 Nov 2009) | 10 lines
  
  Merged revisions 76190 via svnmerge from 
  svn+ssh://pythondev@svn.python.org/python/trunk
  
  ........
    r76190 | r.david.murray | 2009-11-10 13:58:02 -0500 (Tue, 10 Nov 2009) | 3 lines
    
    Update the FAQ entry that explains that assignments in the local scope
    shadow variables in the outer scope (issue 7290).
  ........
................


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Doc/faq/programming.rst

Modified: python/branches/release31-maint/Doc/faq/programming.rst
==============================================================================
--- python/branches/release31-maint/Doc/faq/programming.rst	(original)
+++ python/branches/release31-maint/Doc/faq/programming.rst	Sat Nov 14 23:24:15 2009
@@ -277,39 +277,74 @@
 Core Language
 =============
 
-How do you set a global variable in a function?
------------------------------------------------
-
-Did you do something like this? ::
-
-   x = 1 # make a global
-
-   def f():
-       print x # try to print the global
-       ...
-       for j in range(100):
-           if q > 3:
-               x = 4
-
-Any variable assigned in a function is local to that function.  unless it is
-specifically declared global.  Since a value is bound to ``x`` as the last
-statement of the function body, the compiler assumes that ``x`` is
-local. Consequently the ``print x`` attempts to print an uninitialized local
-variable and will trigger a ``NameError``.
-
-The solution is to insert an explicit global declaration at the start of the
-function::
-
-   def f():
-       global x
-       print x # try to print the global
-       ...
-       for j in range(100):
-           if q > 3:
-               x = 4
+Why am I getting an UnboundLocalError when the variable has a value?
+--------------------------------------------------------------------
 
-In this case, all references to ``x`` are interpreted as references to the ``x``
-from the module namespace.
+It can be a surprise to get the UnboundLocalError in previously working
+code when it is modified by adding an assignment statement somewhere in
+the body of a function.
+
+This code:
+
+   >>> x = 10
+   >>> def bar():
+   ...     print(x)
+   >>> bar()
+   10
+
+works, but this code:
+
+   >>> x = 10
+   >>> def foo():
+   ...     print(x)
+   ...     x += 1
+
+results in an UnboundLocalError:
+
+   >>> foo()
+   Traceback (most recent call last):
+     ...
+   UnboundLocalError: local variable 'x' referenced before assignment
+
+This is because when you make an assignment to a variable in a scope, that
+variable becomes local to that scope and shadows any similarly named variable
+in the outer scope.  Since the last statement in foo assigns a new value to
+``x``, the compiler recognizes it as a local variable.  Consequently when the
+earlier ``print x`` attempts to print the uninitialized local variable and
+an error results.
+
+In the example above you can access the outer scope variable by declaring it
+global:
+
+   >>> x = 10
+   >>> def foobar():
+   ...     global x
+   ...     print(x)
+   ...     x += 1
+   >>> foobar()
+   10
+
+This explicit declaration is required in order to remind you that (unlike the
+superficially analogous situation with class and instance variables) you are
+actually modifying the value of the variable in the outer scope:
+
+   >>> print(x)
+   11
+
+You can do a similar thing in a nested scope using the :keyword:`nonlocal`
+keyword:
+
+   >>> def foo():
+   ...    x = 10
+   ...    def bar():
+   ...        nonlocal x
+   ...        print(x)
+   ...        x += 1
+   ...    bar()
+   ...    print(x)
+   >>> foo()
+   10
+   11
 
 
 What are the rules for local and global variables in Python?


More information about the Python-checkins mailing list