标题
27 评估循环
28 框架
29 基于堆栈的执行
30 字节码指令
31 函数调用
32 方法调用
33 属性查找
34 异常处理
35 发电机
36 协程和异步
37 模式匹配
38 理解
39 封闭件和单元
  • 27.评估循环

    #27.评估循环 The evaluation loop is the central execution engine of CPython. It takes a compiled code object, executes its bytecode instructions, and produces a result or an exception. At a high level, CPython execution looks like this:```text Python source ↓ tokens ↓ parser ↓ AST ↓ symbol table ↓ compiler ↓ code object ↓ frame ↓ evaluation loop ↓ Python result or exception 评估循环存在于 CPython 的解释器实现中。从历史上看,密钥文件一直是 ` Python / ceval…

  • 28. 框架

    #28. 框架 一帧是一次主动执行 Python 代码的运行时记录。当 CPython 调用 Python 函数、执行模块主体、运行类主体、恢复生成器或恢复协程时,它使用类似帧的执行记录来保存当前状态。 代码对象说明要执行什么。 框架表示当前执行的位置以及当前存在的值。 text code object = immutable instructions and metadata frame = mutable execution state for one run of that code 对于这个函数:```python def add(a, b): c = a + b return c 创建的框架 ` add ( 2 , 3 ) ` 包含当前参数值、局部变量槽、堆栈值、指令位置、异常状态以及到执行上下文的链接。 ## 28.1 框架为何存在 Python 程序可以同时有多个活动调用: ``` python def a (): return b () def b (): return c ()…

  • 29. 基于堆栈的执行

    29. 基于堆栈的执行 CPython 使用堆栈机执行大多数字节码。堆栈机使用隐式操作数堆栈,而不是在每条指令中命名显式源寄存器和目标寄存器。 在 CPython 中,该堆栈属于当前帧。它存储对 Python 对象的引用。字节码指令推送对象、弹出对象、检查对象、替换对象以及使用对象计算新结果。 一个简单的表达: python id="kz6m7x" x = a + b 在概念上执行为: text id="eurdpx" LOAD_FAST a push a LOAD_FAST b push b BINARY_OP + pop b and a, push result STORE_FAST x pop result into local x 指令流没有说: text id="ardj57" add local_a, local_b, local_x 相反,它说:```text id="jzzlmf" load a load b add top two stack values store result ## 29.1 为什么 CPython 使用堆栈机 堆栈机为字节码提供了紧凑的表示形式。许多指令不需要显式操作数位置,因为它们在堆栈顶部操作。 例如:…

  • 30. 字节码指令

    30. 字节码指令 字节码指令是 CPython 评估循环执行的操作。它们是经过解析、AST 构造、符号分析和编译后的 Python 代码的紧凑的解释器级形式。 Python 函数,例如:```python id="ya54lv" def add(a, b): return a + b 您可以使用以下命令检查该流 ` dis ` : ``` python id = "7yf46p" import dis def add ( a , b ): return a + b dis . dis ( add ) ``` 输出取决于 Python 版本,但通常显示如下指令: ``` text id = "ot1vx4" LOAD_FAST LOAD_FAST BINARY_OP RETURN_VALUE ``` 这些指令是 CPython 虚拟机的词汇表。 ## 30.1 什么是字节码指令 字节码指令告诉解释器执行一个小操作。 示例: ```…

  • 31. 函数调用

    31. 函数调用 函数调用是 CPython 中最重要的执行路径之一。一次调用同时连接多个系统:字节码执行、帧、参数绑定、描述符、方法、闭包、C API、引用计数、异常和返回处理。 一个简单的调用: python id="wauh11" result = f(1, 2) 在源代码级别看起来很小。在运行时,CPython 必须:```text id="rhdr0d" load the callable load the arguments choose the correct call protocol bind arguments to parameters create or initialize a frame if calling Python code execute the callee return a result or propagate an exception store the result ## 31.1 调用的含义 在 Python 中,调用表达式具有以下一般形式: ``` python id = "a7ltua" callable_object ( arguments ) ``` 括号之前的对象必须是可调用的。…

  • 32. 方法调用

    32. 方法调用 方法调用是通常以属性访问开始的函数调用。它们是 Python 对象模型的核心,因为大多数对象行为都是通过方法公开的。 方法调用例如: python id="l3owku" obj.method(arg) 看起来像一个操作,但 CPython 执行几个概念步骤:```text id="j39rdj" load obj look up attribute method bind obj if needed load arg call the resolved callable return result or raise exception ## 32.1 方法调用是属性访问加调用 源表达式: ``` python id = "xgyvgk" obj . method ( 10 ) ``` 可以理解为: ``` python id = "gg912h" tmp = obj . method tmp ( 10 ) ``` 这是正确的语义模型。首先进行属性查找。然后调用该查找的结果。 这个结果可能是: ``` text…

  • 33. 属性查找

    33. 属性查找 属性查找是用于计算表达式的运行时过程,例如:```python id="5ob0m9" obj.name 一个简单的属性表达式可以触发大量的机制: ``` text id = "b2zmcv" find the object 's type search the type and its base classes handle descriptors check the instance dictionary call custom attribute hooks return a value or raise AttributeError ```属性查找是动态的。结果可能取决于运行时对象、其类、其基类、其实例字典、描述符、元类和用户定义的挂钩。 ## 33.1 基本属性访问 表达式:```python id="67bubm" obj.x ```要求 CPython 查找名为的属性`"x"`在`obj`。 如果找到,则查找返回一个 Python 对象。 如果缺失,则会引发`AttributeError`。 例子:```python id="l53g0p" class C: pass obj = C() obj.x = 10 print(obj.x) ```作业商店`x`在实例字典中:```text id="kz7fxs" obj.__dict__["x"] = 10…

  • 34.异常处理

    34.异常处理 异常处理是 CPython 在操作无法正常完成时使用的控制流系统。它涵盖了明确的 raise 语句、失败的操作、失败的导入、失败的调用、生成器终止、上下文管理器清理、回溯构造以及通过帧的传播。 在源代码级别,异常如下所示: python id="cq34p8" try: value = risky() except ValueError: value = 0 在运行时,CPython 必须:```text id="o1a48o" execute the protected bytecode range detect failure record the active exception find a matching handler restore the frame stack to a valid state jump to handler bytecode run cleanup code propagate if no handler matches ## 34.1 什么是异常 异常是表示异常控制流的对象。 大多数例外是派生类的实例 ` BaseException ` 。 ``` python id = "m6c3g8"…

  • 35. 发电机

    35. 发电机 生成器是可恢复的函数。正常函数以一个返回值开始、运行和结束。生成器可以启动、产生一个值、挂起其帧、稍后从同一指令位置恢复、产生另一个值,然后重复直到完成。 生成器函数是包含以下内容的任何函数体 yield 。 python id="j7t4va" def numbers(): yield 1 yield 2 yield 3 调用此函数不会立即运行主体。 python id="oyb9ik" g = numbers() 该调用创建一个生成器对象。当发电机恢复时,主体启动: python id="9sgmxp" print(next(g)) print(next(g)) print(next(g)) 输出: text id="wj3i3f" 1 2 3 在最后一个值之后,下一个简历将引发 StopIteration 。 35.1 生成器函数与生成器对象 生成器函数是用以下定义的可调用函数 def 。 生成器对象是调用生成器函数时返回的可恢复迭代器。```python id="nckwxg" def gen(): yield 1 print(gen) print(gen()) 从概念上讲: text id="hfh6hz" gen function object gen() generator object suspended execution state code object frame or frame-like state 这与普通函数不同: python…

  • 36. 协程和异步

    36. 协程和异步 协程是用于异步编程的可恢复计算。他们让 Python 代码暂停在 await 点,将控制权返回到事件循环,然后在等待的操作有结果时恢复。 协程类似于生成器,因为两者都在挂起期间保留执行状态。区别在于协议和目的。 生成器向迭代器使用者产生值。 协程等待其他异步操作并最终返回一个最终结果。 python id="o2u8bi" async def fetch(): data = await read() return data 呼唤 fetch() 不运行主体完成。它创建一个协程对象。```python id="9i5ai1" coro = fetch() ## 36.1 协程函数与协程对象 安 ` async def ` 语句创建一个协程函数。 调用协程函数会创建一个协程对象。 ``` python id = "rt8ky9" async def work (): return 42 coro = work () ``` 从概念上讲: ``` text id = "q71j65" work coroutine function object work () coroutine object suspended execution…

  • 37.模式匹配

    37. 模式匹配 模式匹配是Python的结构匹配系统。它是由 match 声明和 case 条款。```python match value: case 0: result = "zero" case [x, y]: result = x + y case {"name": name}: result = name case _: result = None 在 CPython 级别,模式匹配被编译为普通字节码加上专门的匹配指令。解释器评估主题,按顺序尝试每种情况,绑定成功匹配的名称,然后跳转到选定的正文。 ## 37.1 的`match`声明 一个 ` match ` 语句具有一个主题表达式和一个或多个案例。 ``` python match subject : case pattern : body case pattern if guard : body case _ : body ``` 主题表达式被评估一次。 ``` python match compute ():…

  • 38.理解

    38. 理解 推导式是一种紧凑的语法,用于从另一个可迭代对象构建容器或类似生成器的迭代器。 CPython 将它们实现为具有自己的执行范围的编译代码对象。 常见形式: python [x * 2 for x in xs] {x * 2 for x in xs} {x: x * 2 for x in xs} (x * 2 for x in xs) 这些对应于:```text list comprehension set comprehension dict comprehension generator expression ## 38.1 列表理解 列表理解急切地构建一个列表。 ``` python ys = [ x * 2 for x in xs ] ``` 从概念上讲: ``` python ys = [] for…

  • 39. 闭包和单元格

    39. 闭包和单元格 闭包允许嵌套函数在封闭函数返回后使用该封闭函数中的变量。```python def make_adder(n): def add(x): return x + n return add add10 = make_adder(10) print(add10(5)) 输出: text 15 ```变量 n 属于 make_adder , 但 add 以后还是用它。 CPython 通过将捕获的变量移动到单元对象中来支持这一点。内部函数保留对这些单元格的引用。 39.1 嵌套函数 嵌套函数是在另一个函数内部定义的函数。```python def outer(): def inner(): return 1 return inner ```这 def inner 语句执行时 outer 运行。它创建一个函数对象并将其绑定到本地名称 inner 。 呼唤 outer() 返回该函数对象: python fn = outer() print(fn()) 函数对象为 inner 包含: text code object globals dictionary defaults keyword defaults annotations closure…