4

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?

1
  • hi there! i tried running this in google collab with the following code after your snippet to try to replicate your problem but i dont get any such issues. print(foo) test7() print(foo) test7() print(foo) (All are in new lines) Commented Apr 26, 2022 at 3:09

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.