2

I have the following code:

>>> def f(v=1):
...     def ff():
...             print v
...             v = 2
...     ff()
...
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in f
  File "<stdin>", line 3, in ff
UnboundLocalError: local variable 'v' referenced before assignment

I do understand why this message occurs (Python variable scope question), but how can I work with v variable in this case? global v doesn't work in this case.

Community
  • 1
  • 1
rsk
  • 1,266
  • 1
  • 13
  • 20

2 Answers2

6

In Python 3.x, you can use nonlocal:

def f(v=1):
    def ff():
        nonlocal v
        print(v)
        v = 2
    ff()

In Python 2.x, there is no easy solution. A hack is to make v a list:

def f(v=None):
    if v is None:
        v = [1]
    def ff():
        print v[0]
        v[0] = 2
    ff()
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • 1
    Note that the second falls to http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument (calling it a second time without providing `v` prints 2). –  Jun 06 '11 at 19:11
1

You haven't passed v to the inner function ff. It creates its own scope when you declare it. This should work in python 2.x:

def f(v=1):
  def ff(v=1):
    print v
    v = 2
  ff(v)

But the assignment call to v = 2 would not be persistent in other calls to the function.

g.d.d.c
  • 46,865
  • 9
  • 101
  • 111