全局框架与堆栈框架

global frame vs. stack frame

下面的所有内容都来自 www.pythontutor.com 的主页(顺便说一下,这是一个很棒的工具和网站)。

这里是some code

作者将上述代码在当前执行点描述为 "global frame" 和 "stack frames":

我的问题:"global frame"和"stack frame"有什么区别?这个术语是否正确(我用谷歌搜索并得到了各种不同的答案)?

TL DR:

调用函数时,会为本地执行创建一个框架。

加载模块时,会为全局模块执行创建一个框架。

python tutor 不支持显示跨多个文件的执行,因此主模块的初始框架看起来很独特,但您可以想象语句 import foo creating a new frame for模块的执行 foo 就像调用函数一样创建用于执行这些函数的框架。


frames 是您可以与之交互的实际 python 个对象:

import inspect

my_frame = inspect.currentframe()

print(my_frame) #<frame object at MEMORY_LOCATION>

print(my_frame.f_lineno) #this is line 7 so it prints 7
print(my_frame.f_code.co_filename) #filename of this code executing or '<pyshell#1>' etc.
print(my_frame.f_lineno) #this is line 9 so it prints 9

全局框架与局部框架没有什么特别之处 - 它们只是 stack 执行中的框架:

Python 3.6.0a1 (v3.6.0a1:5896da372fb0, May 16 2016, 15:20:48) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import inspect
>>> import pprint
>>> def test():
...     pprint.pprint(inspect.stack())
... 
>>> test() #shows the frame in test() and global frame
[FrameInfo(frame=<frame object at 0x1003a3be0>, filename='<stdin>', lineno=2, function='test', code_context=None, index=None),
 FrameInfo(frame=<frame object at 0x101574048>, filename='<stdin>', lineno=1, function='<module>', code_context=None, index=None)]
>>> pprint.pprint(inspect.stack()) #only shows global frame
[FrameInfo(frame=<frame object at 0x1004296a8>, filename='<stdin>', lineno=1, function='<module>', code_context=None, index=None)]

当你调用一个函数(用 python 源代码定义)时,它会为它的本地执行添加一个框架到堆栈,当一个模块被加载时,为模块的全局执行添加一个框架被添加到堆栈中。

框架没有任何标准化的命名约定,因此 Internet 上的术语可能会相互矛盾。通常您可以通过文件名和函数名来识别它们。 Python 将全局帧称为名为 <module> 的函数,如上例 (function='<module>') 或错误中所示:

>>> raise TypeError
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    raise TypeError               # ^ up there
TypeError
                               

“全局”和“函数”框架之间唯一真正的区别是 全局框架 全局变量和局部变量之间没有区别:

>>> my_frame.f_globals is my_frame.f_locals
True

这就是为什么将 global 关键字放在全局框架中是没有意义的,它表示变量名称 - 在分配时 - 应该放在 .f_globals 而不是 .f_locals 中。但除此之外,所有帧都几乎相等。