Quark概述:Python执行模型
Source: Dev.to
(请提供您希望翻译的具体文本内容,我将为您将其翻译成简体中文,同时保留原始的格式、Markdown 语法以及代码块和 URL。)
Python 执行模型概述
什么是 Python 执行模型?
当你运行一个 Python 程序时,Python 会遵循一个过程来决定 会发生什么 以及 以何种顺序。这个过程称为 Python 执行模型。它控制代码如何分组、值如何存储以及出错时会发生什么。
- 代码块 – 语句的逻辑分组。
- 执行帧 – 保存块状态并链接到下一个块的对象。
- 命名空间 – 保存名称及其关联值的映射。
- 异常 – 当错误发生时被抛出的对象。
这四个概念——代码块、执行帧、命名空间和异常——构成了执行模型。
Python 让你使用一个管理块、名称和错误的帧来运行代码。
def greet():
name = "Ada"
print("Hello,", name)
greet()
# prints:
# Hello, Ada在上面的例子中,greet() 在 新的代码块 和 新的执行帧 中运行。变量 name 存在于该帧的 局部命名空间 中。
Python执行模型的历史时间线
Python的执行模型来源于哪里?
Python的执行模型借鉴了早期语言(ALGOL、Lisp)的思想,同时加入了安全的名称处理和灵活的错误控制。下面的时间线展示了四个核心概念的演变。
| 年份 | 里程碑 |
|---|---|
| 1960 | 代码块和作用域 在ALGOL中引入——嵌套块并具有明确的局部与全局规则。 |
| 1970s | 基于栈的帧 在Lisp和C中变得常见——调用栈和局部作用域规则。 |
| 1991 | 代码块和帧 在Python 0.9.0中加入,以支持安全的函数调用和模块化设计。 |
| 1995 | 异常和 try/except 被引入(try、except、raise)。 |
| 2001 | 通过 globals() 和 locals() 实现 动态命名空间访问。 |
| 2006 | exec 和 eval 获得可选的命名空间参数。 |
| 2025 | 执行模型稳定——对交互式、脚本式和基于模块的代码提供强力支持。 |
Python 执行模型的问题与解决方案
如何正确使用 Python 执行模型?
Python 按步骤执行代码,创建代码块、构建帧、使用命名空间,并在需要时抛出异常。下面列出常见问题以及使用该模型的解决办法。
1. 查看 Python 运行代码的位置
问题: 你想追踪 Python 何时进入和退出每个代码块(即查看活动帧)。
解决方案: 使用 sys._getframe()(或更高级的 inspect 模块)检查调用栈。
import sys
def outer():
def inner():
frame = sys._getframe()
print("Now running:", frame.f_code.co_name)
inner()
outer()
# prints:
# Now running: inner每当 Python 进入一个新块时,都会创建一个新的 执行帧,其中保存代码对象及其命名空间。
2. 区分局部和全局名称
问题: 你在函数内部有一个变量 value,在模块层级也有一个同名的 value。Python 会使用哪一个?
解决方案: 每个帧都有 两个命名空间——局部 和 全局。Python 先在局部命名空间查找,然后才是全局命名空间。
value = "global"
def show():
value = "local"
print("Value is:", value)
show()
# prints:
# Value is: local在 show() 中,局部的 value 会遮蔽全局的 value。
3. 复用具有独立作用域的代码块
问题: 你需要重复执行一组语句,但不想影响块外的变量。
解决方案: 定义一个函数(或其他可调用对象)——每次调用都会获得一个全新的 局部命名空间。
x = 1
def block():
x = 2
print("Inside block:", x)
block()
print("Outside block:", x)
# prints:
# Inside block: 2
# Outside block: 1函数的局部命名空间将其变量与外围模块隔离。
4. 在不停止程序的情况下处理错误
问题: 你想尝试可能会失败的操作,但不希望整个程序崩溃。
解决方案: 使用 异常 与 try/except 块。
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero.")
# prints:
# Cannot divide by zero.Python 抛出异常;except 块捕获它,使程序能够继续运行。
5. 检查当前的全局和局部名称
问题: 你需要查看当前全局和局部作用域中已定义的名称及其值。
解决方案: 使用内置的 globals() 和 locals() 函数。
def demo():
a = 10
b = 20
print("Local names:", locals())
print("Global names:", globals().keys())
demo()locals()返回当前 局部 命名空间的字典。globals()返回 模块级 命名空间的字典。
摘要
Python 的执行模型围绕 代码块、执行帧、命名空间 和 异常 构建。了解这些组成部分如何相互作用可以帮助你:
- 使用帧跟踪程序流程。
- 区分局部变量和全局变量。
- 将代码隔离在自己的作用域中。
- 优雅地处理错误。
- 检查当前的执行环境。
掌握这些知识后,你就能编写更清晰、更健壮的 Python 代码,充分利用语言底层的执行机制。
Source: …
当前命名空间以及如何打印它们的名称和值
问题
您想查看全局和局部命名空间的内容。
解决方案
Python 提供了内置函数 globals() 和 locals() 来实现此目的。
Python 让您使用内置查找工具读取命名空间。
x = 42
def show():
y = "Ada"
print("Globals:", list(globals().keys()))
print("Locals:", list(locals().keys()))
show()
# prints:
# Globals: ['__name__', '__doc__', ..., 'x']
# Locals: ['y']您可以使用这些工具查看每个作用域中定义了哪些名称。
行动号召
点赞、评论、分享并订阅!
觉得有帮助吗?请点击下面的赞按钮告诉我。也欢迎在评论区留下您的想法!如果想看到更多类似内容,别忘了订阅。感谢阅读!
Mike Vincent – 一位来自加利福尼亚州洛杉矶的美国软件工程师和应用开发者。
More about Mike Vincent