3

Possible Duplicate:
Short Description of Python Scoping Rules

I wrote two simple functions:

# coding: utf-8
def test():
    var = 1 
    def print_var():
        print var 
    print_var()
    print var 

test()
# 1
# 1
def test1():
    var = 2 
    def print_var():
        print var 
        var = 3 
    print_var()
    print var 

test1()
# raise Exception

In comparison, test1() assigns value after print var, then raise an Exception: UnboundLocalError: local variable 'var' referenced before assignment, I think the moment I call inner print var, var has a value of 2, am I wrong?

Community
  • 1
  • 1
iMom0
  • 12,493
  • 3
  • 49
  • 61
  • 1
    See this link: http://stackoverflow.com/questions/423379/using-global-variables-in-a-function-other-than-the-one-that-created-them – Hans Then Sep 12 '12 at 06:42
  • @HansThen: No, a `global` declaration would not help here, as `var` is a function-scope variable. In python 3 you'd use `nonlocal` but in python 2 (as used here) there is no way you can do what the OP is trying to do. – Martijn Pieters Sep 12 '12 at 06:53

1 Answers1

1

Yes, you're incorrect here. Function definition introduces a new scope.

# coding: utf-8
def test():
    var = 1 
    def print_var():
        print var    <--- var is not in local scope, the var from outer scope gets used
    print_var()
    print var 

test()
# 1
# 1
def test1():
    var = 2 
    def print_var():
        print var     <---- var is in local scope, but not defined yet, ouch
        var = 3 
    print_var()
    print var 

test1()
# raise Exception
wim
  • 338,267
  • 99
  • 616
  • 750
  • 1
    Hang on, I thought python did not look ahead when executing. How does python know that `var` is *going* to be a local variable in the second `print_var` function? – Lauritz V. Thaulow Sep 12 '12 at 06:45
  • So when python parses the function it saves a list of the names of all variables that are assigned to within. Then at call time it sees that `var` is in this list, and complains since it's not defined yet. Is this local variable list accessible? – Lauritz V. Thaulow Sep 12 '12 at 06:53
  • 1
    @lazyr: Exactly; variables are bound to a scope at compile time. Assignment is a storing operation, and binds that variable to the local scope *unless marked global*. If there is no assignment, the variable is 'free' and looked up in surrounding scopes, but this is bound *as well* to that specific scope. See [Python nested scopes with dynamic features](http://stackoverflow.com/questions/12338713/12338782#12338782) for example. – Martijn Pieters Sep 12 '12 at 06:56
  • @Martijn Can I access the scope of a function and see what its local variables are called? – Lauritz V. Thaulow Sep 12 '12 at 07:22
  • @wim I meant from outside the function. We've established such a list exists, but where is it? – Lauritz V. Thaulow Sep 12 '12 at 07:27
  • 2
    @lazyr: Yes, see http://docs.python.org/reference/datamodel.html, `afunction.func_code.co_varnames` are local variables. `co_freevars` and `co_cellvars` are interesting in this respect; they are variables taken from the surrounding scope (non-global) and variables referred to by nested functions, respectively. – Martijn Pieters Sep 12 '12 at 07:33
  • @wim Right. Martijn answered my question, and I found [this](http://stackoverflow.com/a/370380/566644) answer that details the lexing process that raises UnboundLocalError. – Lauritz V. Thaulow Sep 12 '12 at 07:36