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,064
  • 1
  • 11
  • 18

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
  • 530,615
  • 113
  • 910
  • 808
  • 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
  • 44,141
  • 8
  • 97
  • 109