Python中的框架类型

4 投票
2 回答
3893 浏览
提问于 2025-04-17 20:22

在一个python参考手册中提到:

代码块是在一个执行框架中运行的。这个框架包含一些管理信息(用于调试),并决定在代码块执行完后,接下来要在哪里和如何继续执行。

还有:

框架对象代表执行框架。它们可能出现在追踪对象中。

但是我不太明白框架是怎么工作的。我怎么才能访问当前的框架对象?框架对象是什么时候创建的?每次新的代码块开始执行时,框架对象都会被创建吗?

2 个回答

0

在Python 3中,理解“帧”是很重要的,特别是当你在维护对内存使用敏感的生产代码时,比如深度学习模型。

帧是一些对象,它们代表了当一个函数被调用时,存储局部变量的内存区域。这些帧可以被存储和操作,这正是调试工具所做的事情。了解Python是如何处理帧的,可以帮助你避免内存泄漏。

每次调用一个函数时,都会创建一个新的帧来保存这个函数的变量和参数。通常情况下,当函数正常执行完毕后,这些帧会被销毁。然而,如果发生了异常,相关的帧和所有父帧会被存储在一个追踪对象中,这个对象是异常对象的一个属性(__traceback__)。如果这个异常对象存在的时间很长,就可能导致内存泄漏,因为它们会保留这些帧,而所有相关的局部变量也不会被垃圾回收。

这件事情非常重要。

举个例子,这就是为什么即使你没有创建引用循环,也需要调用file对象的close方法,因为文件对象可能会被存储在异常的追踪对象中。这会导致文件在超出作用域后仍然无法被垃圾回收。

在像Jupyter这样的交互式Python环境中,这个问题更严重,因为每个未处理的异常可能会在几个地方永远存在。我正在寻找解决这个问题的方法,因此我发现了这个问题。

在Python中,类型模块提供了FrameTypeTracebackType这两种类型,分别代表帧和追踪信息。然而,你不能直接实例化这些类型。https://docs.python.org/3/library/types.html#types.FrameType

tracback属性是在Python 3中引入的,具体内容可以参考PEP 3134,这篇文档详细讲解了这个变化的影响,值得好奇的人去阅读。

1

这些框架是函数调用时创建的堆栈框架的表示。正常编程中你不需要去访问它们。每次调用一个函数时,确实会创建一个新的框架,而当函数结束或者抛出未处理的异常时,这个框架就会被销毁。由于函数调用可以嵌套很多层,所以你的程序会有很多嵌套的堆栈框架。但即使Python让你可以访问这些框架,随便去操作它们并不是一个好的编程习惯(除非你在写调试器或者类似的应用)。

撰写回答