访问 ipython 内的全局变量

Accessing global variables within ipython

ipython 中,我使用 %run 从文件中执行以下代码:

foo = 32

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

我的 ipython 成绩单如下:

$ 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]: 

我的问题是:为什么在 ipython 中查询 foo 的值总是 return 32 而 test7() 例程似乎在增加它?

有没有办法让我看到 foo 的值与 test7() 函数看到的值相同?

您可以将 %run-i flag 传递给“运行 IPython 命名空间中的文件而不是空文件。”

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

我觉得文档有点混乱,但我认为他们试图用以下方式解释行为:

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).

另外值得注意的是 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.

foo 总是 32 的原因是因为 foo 变量存储在特定内存中 space 如果你不通过 -i 作为@Mark提到它将 return 存储在该特定内存中的值 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

您可以注意到 32 常量和 foo 变量具有相同的 ID