global frame vs. stack frame

2019-04-10 22:48发布

问题:

Everything below is from the main page of www.pythontutor.com (a fantastic tool and website by the way).

Here's some code

Here's what the author describes as the "global frame" and the "stack frames" at the current point of execution for the above code:

My question: What's the difference between "global frame" and the "stack frame"? Is this terminology even correct (I googled around and got all kinds of different answers)?

回答1:

frames are actual python objects that you can interact with:

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

There is nothing particularly special about a global frame vs a local frame - they are just frames in the stack of execution:

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

When ever you call a function (defined with python source code) it will add a frame for it's local execution to the stack, when ever a module is loaded a frame for the global execution of the module is added to the stack.

Frames don't have any standardized naming convention, so terminology accross the internet will probably contradicting. Usually you can identify them by the file and function name. Python refers to global frames as being a function named <module> as can be seen in above example (function='<module>') or in errors:

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

The only real difference between "global" and "function" frames is that with global frames there is no distinction between global and local variables:

>>> my_frame.f_globals is my_frame.f_locals
True

Which is why putting the global keyword in the global frame is meaningless, it indicates variable names that - when assigned - should be put in .f_globals instead of .f_locals. But other then that all frames are pretty much equal.