Home > Mobile >  Accessing global variables within ipython
Accessing global variables within ipython

Time:04-26

In ipython I am using %run to execute the following code from a file:

foo = 32

def test7():
    global foo
    print("foo before:", foo)
    foo  = 1
    print("foo after:", foo)

My ipython transcript goes as follows:

$ ipython
Python 3.10.2 (tags/v3.10.2:a58ebcc, Jan 17 2022, 14:12:15) ...

In [1]: %run "a1.py"

In [2]: foo
Out[2]: 32

In [3]: test7()
foo before: 32
foo after: 33

In [4]: foo
Out[4]: 32

In [5]: test7()
foo before: 33
foo after: 34

In [6]: foo
Out[6]: 32

In [7]: 

My question is: why does querying the value of foo within ipython always return 32 when the test7() routine seems to be incrementing it?

And is there a way I can see the same value of foo that the test7() function is seeing?

CodePudding user response:

The reason why foo is always 32 is because foo variable is stored in an specific memory space and if you don't pass -i as @Mark mentions it will return the value stored in that specific memory space:

In [1]: %run "a1.py"

In [2]: foo
Out[2]: 32

In [3]: id(foo)
Out[3]: 1543004777744

In [4]: id(32)
Out[4]: 1543004777744

In [5]: test7()
foo before: 32
foo after: 33

In [6]: id(foo)
Out[6]: 1543004777744

In [7]: id(33)
Out[7]: 1543004777776

You can notice 32 constant and foo variable have the same ID value

CodePudding user response:

You can pass %run the -i flag to "run the file in IPython’s namespace instead of an empty one."

In [1]: %run -i "a1.py"

In [2]: foo
Out[2]: 32

In [3]: test7()
foo before: 32
foo after: 33

In [4]: foo
Out[4]: 33

In [5]: test7()
foo before: 33
foo after: 34

In [6]: foo
Out[6]: 34

I find the docs a little confusing, but I think they are trying to explain the behavior with:

The file is executed in a namespace initially consisting only of __name__=='__main__' and sys.argv constructed as indicated. It thus sees its environment as if it were being run as a stand-alone program (except for sharing global objects such as previously imported modules). But after execution, the IPython interactive namespace gets updated with all variables defined in the program (except for __name__ and sys.argv).

Also worth noting is this from the python docs:

Programmer’s note: global is a directive to the parser. It applies only to code parsed at the same time as the global statement. In particular, a global statement contained in a string or code object supplied to the built-in exec() function does not affect the code block containing the function call, and code contained in such a string is unaffected by global statements in the code containing the function call.

  • Related