How does 'global' behave under an if statement?

global, python, python-3.x

Solution

Yes, you're understanding things correctly.

The `global` statement isn't something that's evaluated at runtime. It's really a directive to the parser that essentially tells it to treat all listed identifiers (`a` here) as referring to the global scope. From the docs on the `global` statement:

The global statement is a declaration which holds for the entire current code block. It means that the listed identifiers are to be interpreted as globals.

It then continues to state how `global` is really is a directive:

Programmer’s note: `global` is a directive to the parser.

Using it conditionally doesn't make any difference: its presence has already been detected in the parsing stage and, as a result, the byte-code generated for grabbing the names has already been set to look in the global scope (with `LOAD/STORE GLOBAL`).

This is why, if you `dis.dis` a function containing a `global` statement, you won't see any relevant byte-code for `global`. Using a silly function:

from dis import dis
def foo():
    "I'm silly"
    global a  

dis(foo)
  2           0 LOAD_CONST               0 (None)
              2 RETURN_VALUE

Nothing is generated for `global a` because the information it provides has already been used!

Problem

In my program, I wanted a variable global only under some circumstances. Say it looks like this: ``` a = 0 def aa(p): if p: global a a = 1 print("inside the function " + str(a)) print(a) aa(False) print("outside the function " + str(a)) ``` I was expecting the result to be: ``` 0 inside the function 1 outside the function 0 ``` However it turned out to be: ``` 0 inside the function 1 outside the function 1 ``` So, I was thinking, "Okay maybe the Python compiler makes the variable global whenever it sees the 'global' keyword no matter where it is located". Is this how Python works with global vars? Am I misunderstanding?

Original source