views:

80

answers:

3

The following code:

x = 0
print "Initialization: ", x
def f1():
    x = 1
    print "In f1 before f2:", x
    def f2():
        global x
        x = 2
        print "In f2:          ", x
    f2()
    print "In f1 after f2: ", x
f1()
print "Final:          ", x

prints:

Initialization:  0
In f1 before f2: 1
In f2:           2
In f1 after f2:  1
Final:           2

Is there a way for f2 to access f1's variables?

A: 

remove global statement:

>>> x
0
>>> def f1():
    x = 1
    print(x)
    def f2():
        print(x)
    f2()
    print(x)


>>> f1()
1
1
1

if you want to change variable x from f1 then you need to use global statement in each function.

SilentGhost
That won't allow you to assign to x from f2.
interjay
that was fixed, interjay. However, from the question it is not clear that OP wants to assign to `x`. He says *access*.
SilentGhost
+1  A: 

In Python 3, you can define x as nonlocal in f2.

In Python 2, you can't assign directly to f1's x in f2. However, you can read its value and access its members. So this could be a workaround:

def f1():
    x = [1]
    def f2():
        x[0] = 2
    f2()
    print x[0]
f1()
interjay
+3  A: 

You can access the variables, the problem is the assignment. In Python 2 there is no way to rebind x to a new value. See PEP 227 (nested scopes) for more on this.

In Python 3 you can use the new nonlocal keyword instead of global. See PEP 3104.

nikow