views:

57

answers:

3

Hello everyone!

I am learning Python and just had this question. It possibly has no practical worth, I'm asking this out maybe because of a pedantic curiosity.

I have a function:

def f():
    x = 12    #this is a local variable
    global x  #this is a global I declared before
    x = 14    #changes global x

    <How can I return the local x?>

I'm aware that this is ugly and I do get a Syntax Warning. Just wanted to know how to "get back" my local variable.

Thanks to everyone.

+4  A: 

Your code isn't doing what you think it is and there's no way to change it do what you describe. You can't "revert" what globals does since it has no effect at run time.

The global keyword is interpreted at compile time so in the first line of f() where you set x = 12 this is modifying the global x since the compiler has decided the x refers to the x in the global namespace throughout the whole function, not just after the global statement.

You can test this easily:

>>> def g():
...     x = 12
...     y = 13
...     global x
...     print "locals:",locals()
...
<stdin>:4: SyntaxWarning: name 'x' is assigned to before global declaration
>>> g()
locals: {'y': 13}

The locals() function gives us a view of the local namespace and we can see that there's no x in there.

The documentation says the following:

Names listed in a global statement must not be used in the same code block textually preceding that global statement.

Names listed in a global statement must not be defined as formal parameters or in a for loop control target, class definition, function definition, or import statement.

The current implementation does not enforce the latter two restrictions, but programs should not abuse this freedom, as future implementations may enforce them or silently change the meaning of the program.

Just give the local variable a different name.

Dave Webb
Thanks so much.
Learner
+4  A: 

I very much doubt that it can be done.

>>> x = 1
>>> def f():
...     x = 12
...     global x
...     print x
... 
<stdin>:3: SyntaxWarning: name 'x' is assigned to before global declaration
>>> f()
12
>>> x
12

As you can see, even without an explicit assignment to x after the global keyword, python syncs up the the values of the two. To see why, you have to disassemble it.

>>> dis.dis(f) # different f with print statement removed for clarity
  2           0 LOAD_CONST               1 (12)
              3 STORE_GLOBAL             0 (x)

  3           6 LOAD_CONST               0 (None)
              9 RETURN_VALUE        
>>> 

The global keyword isn't represented here at all but the assignment statement gets compiled as STORE_GLOBAL. After you do it, it's done. Use globals with care and the global keyword with greater care.

aaronasterling
@AaronMcSmooth : +1 Deleted my own post as this explains it well.
pyfunc
You are amazing. Thanks.
Learner
+1  A: 

It is not possible to undo the effect of a global statement.

A global statement applies for the entire duration of the function in which it appears, regardless of where in the function it is, and regardless of whether it's executed. So, for example, in the assignment in the following function:

def f():
    x = 3
    if False:
        global x

x is still treated as global.

So it wouldn't make sense to have another statement to undo its effect afterwards, since a global "statement" is not so much a statement, that is executed at some point during the function, as a declaration about the behavior of the function as a whole.

jchl