diff options
author | R. David Murray <rdmurray@bitdance.com> | 2009-11-14 22:21:32 (GMT) |
---|---|---|
committer | R. David Murray <rdmurray@bitdance.com> | 2009-11-14 22:21:32 (GMT) |
commit | c04a69461483cb1a484863d69b1c4a0c4e6271d2 (patch) | |
tree | 0a72bcc12b685f29d7eef0ea42354923f1ee2865 | |
parent | e0b479e78191fce6a5f81d46bc2344d77b4cb4c2 (diff) | |
download | cpython-c04a69461483cb1a484863d69b1c4a0c4e6271d2.zip cpython-c04a69461483cb1a484863d69b1c4a0c4e6271d2.tar.gz cpython-c04a69461483cb1a484863d69b1c4a0c4e6271d2.tar.bz2 |
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).
........
-rw-r--r-- | Doc/faq/programming.rst | 101 |
1 files changed, 68 insertions, 33 deletions
diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index faa3b80..0bc9411 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -277,39 +277,74 @@ confusing API to your users. 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 - -In this case, all references to ``x`` are interpreted as references to the ``x`` -from the module namespace. +Why am I getting an UnboundLocalError when the variable has a value? +-------------------------------------------------------------------- + +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? |