[Tutor] Question about why a list variable is apparently global.

boB Stepp robertvstepp at gmail.com
Thu Nov 27 17:07:26 CET 2014


On Thu, Nov 27, 2014 at 9:33 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Thu, Nov 27, 2014 at 09:00:48AM -0600, boB Stepp wrote:

[...]

> But there is a subtlety that you may not expect:
>
> py> class Tricky:
> ...     print(x)
> ...     x = "inner"
> ...     print(x)
> ...
> outer
> inner

Actually, this is what you had me primed to expect. However, ...

> So although classes introduce a new scope, they are not like functions.
> In a function, the above would lead to an error (try it and see).

>>> def tricky_func():
              print(x)
              x = "inner"
              print(x)

>>> tricky_func()
Traceback (most recent call last):
    File "<pyshell#20>", line 1, in <module>
       tricky_func()
    File "<pyshell#19>", line 2, in tricky_func
        print(x)
UnboundLocalError: local variable 'x' referenced before assignment

This surprised me! So I did:

>>> def tricky_func2():
              y = x
              print(x)

>>> tricky_func2()
outer

So why does not print(x) see the global x and instead looks for the
local x? And why is this different between classes and functions?

> * Every module is a separate scope.
>
> * `def` and `class` introduce new scopes.
>
> * Other indented blocks (for, while, if etc.) do not.

Alan's reference to indentation level had me trying to prove the
opposite--unsuccessfully.

> * But lambda expressions do.
>
> * Generator expressions have their own scope too.
>
> * In Python 3 only, so do list comprehensions (and dict and set
>   comprehensions). But not in Python 2.

This is good to know this difference as at work I'm in Python 2.4.4
and at home Python 3.4

-- 
boB


More information about the Tutor mailing list