Given:
def f():
x = 0
def g():
h()
def h():
x += 1
print(x)
g()
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in f
File "<stdin>", line 4, in g
File "<stdin>", line 6, in h
UnboundLocalError: local variable 'x' referenced before assignment
>>>
How can I make h
see the x
variable?
Thanks.
EDIT
Should have mentioned it earlier, I am using Python 2.7.3
You can make x
a function attribute:
def f():
f.x = 0
def g():
h()
def h():
f.x += 1
print(f.x)
g()
Also, as of Python 3, you can use nonlocal
keyword.
If you're using Python 3, you use the nonlocal
keyword. Put nonlocal x
at the beginning of function h
. If you're using Python 2.x, a workaround is making x
a list with one element, so you can modify it:
def f():
x = [0]
def g():
h()
def h():
x[0] += 1
print x[0]
g()
f()
In Python 3 just use nonlocal
:
def f():
x = 0
def g():
h()
def h():
nonlocal x
x += 1
print(x)
g()
f()
Can't we put x
as function arguments as workaround
def f():
x = 0
def g():
h(x)
def h(x):
x += 1
print(x)
g()
f()
Easiest is to use a dict or empty class, e.g.:
class Empty:
x = 0
def f():
closure1 = dict(x=0)
closure2 = Empty()
def g(): h(x)
def h(x):
closure1["x"] += 1
closure2.x += 1
g()
print closure1["x"], closure2.x
Although many good solutions were already provided, they have corner cases:
- nonlocal, per Ashwini, is Python 3.x only
- function attribute, per ovgolovin, will fail is
f
is redefined and later called by reference