Python虚拟机需要CPU来执行字节码吗?

2023-12-03

Python虚拟机需要CPU来执行字节码吗?字节码是否转换为机器码,然后CPU参与该过程?


为了在任何计算机上运行应用程序,其代码必须始终以某种方式转换为机器代码,然后由 CPU 执行。问题在于这种情况何时以及如何发生。

让我尝试向您展示 Python 如何有效地执行字节码。

编译器与解释器

想象一下,你计算机中的 CPU 除了拉丁语之外什么都不懂。您想向其发送一封包含详细说明或请求的信件,但您不会说拉丁语。因此,您将聘请一位翻译人员:为您将您的“英语”字母(或您使用的任何语言)翻译成拉丁语的人。

编译语言像 C 或 Rust 一样,将整个字母翻译成拉丁文,然后进行真正的润色。结果是一封翻译后的信件充满诗意且使用复杂的语言。一个口译员另一方面,像 Python 一样,一次翻译一个单词或一个句子;它更像是您在新闻中遇到的口译员,可以翻译外语人士所说的内容。

Bytecode

从 C、Rust 或 Python 等语言到机器代码的完整翻译过程非常复杂,需要仔细分析原始程序代码。为了避免一遍又一遍地分析你的程序代码,Python解释器只会执行一次,然后生成bytecode这是 Python 代码的非常接近的表示,但分为基本元素。

让我们看一个非常简单的 Python 函数:

def f(x):
    y = (x + 1)*(x - 1)
    return y

该函数中的计算包含多项计算,所有计算都必须按正确的顺序执行。字节码反映了这一点:

    LOAD_VAR     x    # x+1
    LOAD_CONST   1
    ADD
    LOAD_VAR     x    # x-1
    LOAD_CONST   1
    SUBTRACT
    MULTIPLY          # ()*()
    STORE_VAR    y    # y = ...
    LOAD_VAR     y
    RETURN

事实上,Python 中的字节码通常是 Python 代码本身的非常接近的表示,只是分解为“原子”简单操作的片段。

在内部,每个字节码指令都有一个数值(实际上适合一个字节,因此得名)。例如,LOAD_VAR = 124, LOAD_CONST = 100, ADD = 23等等。而局部变量和常量值也是通过数字来表示的。因此,如果我们分配x = 01 and y = 02,上面的代码就变成:

  124,  01, 100,  01,  23, 124,  01, 100,  01,  
   24,  20, 125,  02, 124,  02,  83

执行字节码

下面您将找到一个简单且简约的“Python 字节码”解释器,它能够执行我们在开始时定义的函数。这Python 的实际字节码解释器用 C 编写,因此编译为高效的机器代码。但原理是完全一样的。

它使用一个stack保存中间值。也就是说,每个操作的结果都附加到一个列表中。进一步处理这些结果的操作将它们从列表的末尾取出,执行某些操作(例如将它们加在一起),然后将结果附加回列表(但是在执行减法或除法等操作时必须小心,以保持正确的顺序)。

将字节码排列成指令和参数对很方便。有些指令(如 ADD)没有参数,所以我们只使用0在这种情况下。但这里使用的代码仍然是上面介绍的字节码。

def execute(bytecode, consts, vars):
    stack = []
    for (instr, arg) in bytecode:
        if instr == 20:
            stack.append(stack.pop() * stack.pop())
        elif instr == 23:
            stack.append(stack.pop() + stack.pop())
        elif instr == 24:
            second = stack.pop()
            first  = stack.pop()
            stack.append(first - second)
        elif instr == 83:
            return stack.pop()
        elif instr == 100:
            stack.append( consts[arg] )
        elif instr == 124:
            stack.append( vars[arg] )
        elif instr == 125:
            vars[arg] = stack.pop()

my_bytecode = [
  (124, 1), (100, 1), (23, 0), (124, 1), (100, 1), 
   (24, 0), (20, 0), (125, 2), (124, 2),  (83, 0)
]
my_consts = [ None, 1 ]   
my_vars   = [ x, 0 ]
execute(my_bytecode, my_consts, my_vars)

您实际上可以查看常量值列表(尽管它们实际上是元组,而不是列表),或者使用以下方式定义局部变量的顺序:

print(f.__code__.co_code)      # prints the bytecode
print(f.__code__.co_consts)    # prints (None, 1)
print(f.__code__.co_varnames)  # prints ('x', 'y')

更方便的是使用inspect and dis当然是模块。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python虚拟机需要CPU来执行字节码吗? 的相关文章

随机推荐

  • Scipy griddata 在循环/内存泄漏内不起作用

    我在循环内使用 Scipy 的 griddata 时遇到问题 基本上发生的情况是 在循环运行时内存会无限制地增长 要重现该问题 只需将示例放入 http docs scipy org doc scipy reference generate
  • for循环读取带空格的文件名

    我正在尝试扫描目录中的文件以查找其中的文本 但是每当我遇到从 Windows 中添加到末尾添加 Copy 的文件时 程序都不会读取它 我尝试在传递的名称中使用引号 但没有骰子 FOR R F in CDP do for f tokens a
  • 如何在Asp.Net中的Server.Transfer之前设置响应头?

    我有一个页面 根据某些条件 我要么执行 Response Redirect 要么执行 Server Transfer 现在我想为这两种情况添加标题 所以我正在做以下事情 Response AddHeader Vary User Agent
  • 在 Swift 中向 Firebase 数组添加项目,无需先观察数组

    目前 我通过首先观察数组 附加我的新帖子 然后更新引用来向我的 Firebase 数组添加一个新帖子 REF USER child UID observeSingleEventOfType Value withBlock snapshot
  • 带有文本文件的 Chrome 扩展 [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我是 chrome 扩展的新手 我需要开发一个可以处理 text json 文件的 chrome 扩展 应该能够执行读写操作 文件将存储在同一台机器上 路径可能是 D abc x
  • jquery下拉菜单和ajax窗口之间的冲突

    我有一个 jquery 下拉菜单和一个模式窗口 它是 ajax 的触发器 当您单击 ajax 链接时会出现问题 当您关闭它时 下拉列表将不再起作用 因此 当您不单击 ajax 时 下拉菜单就会起作用 当您单击链接并将其关闭时 下拉菜单不显示
  • 为不同包中的对象创建通用转换器

    我有 5 个 Web 服务 A B C D 和 E 每个服务都有自动生成的对象 其结构完全相同 但名称不同且位于不同的包中 com ws a carA contains parameters and com ws a wheelA com
  • Android achartengine 简单饼图

    我正在跟进此链接中的示例和 创建了一个类如下 public class aChartExample public Intent execute Context context int colors new int Color RED Col
  • 在 Keras 中绘制模型

    我正在尝试在 Keras 中绘制我的模型 如下所示 Plot model graph tf keras utils plot model model to file Model1 png from IPython display impor
  • 如何连接 HIVE 中的两个表。

    我有两个表 A 和 B 它们都具有以下结构 Table A Name Age actualdate no Table B City sdate edate id 我希望使用 JOIN 获取 A 和 B 中的所有字段 其中 id no 且 s
  • 查找 int[] 数组中最受欢迎的元素

    int a new int 10 1 2 3 4 5 6 7 7 7 7 我怎样才能写一个方法并返回7 我想让它保持原生状态 而不需要列表 地图或其他助手的帮助 仅数组 试试这个答案 一 数据 int a 1 2 3 4 5 6 7 7 7
  • 静态方法无法访问实例字段?

    我读过很多关于静态字段的文章 静态方法无法访问实例字段 字段 因为实例字段仅存在于该类型的实例上 但我们可以在静态类中创建和访问实例字段 请找到下面的代码 class Program static void Main string args
  • 通过将集合划分为两个子集来查找可以由集合形成的最大总和

    说明 Given a set of numbers S Find maximum sum such that Sum A1 Sum A2 Where A1 S and A2 S and A1 A2 And Sum X is the sum
  • 在 Android 中向 SQLite 表添加一列?

    我想向现有 SQLite 数据库的表中添加另一列 这可能吗 还是我需要做一些特定的事情来升级它 如果是这样 我该如何去做呢 Use the 修改表命令 ALTER TABLE my table ADD COLUMN new column
  • 从 Google 通讯录获取 Google+ ID

    我正在使用 Google Contacts API 提取用户的联系人电子邮件地址和姓名 有没有办法也获得这些人的 Google ID 联系人 API 将返回profile链接 如果 G 个人资料与联系人条目链接 这是一个例子
  • PostgreSQL 中的级联删除

    我有一个数据库 其中有几十个与外键互连的表 一般情况下我想要默认的ON DELETE RESTRICT这些约束的行为 但是 当尝试与顾问共享数据库快照时 我需要删除一些敏感数据 我希望我的记忆DELETE FROM Table CASCAD
  • Laravel Eloquent - 查询数据透视表

    在我的 Laravel 应用程序中 我有三个数据库表 分别称为用户 项目和角色 它们之间存在 m n 关系 因此我还有名为 project user role 的数据透视表 数据透视表包含 user id project id 和 role
  • 如何在执行 MSTest 测试期间写入 Console.Out

    Context 控制台输出未出现是因为后端代码未在测试上下文中运行 你可能最好使用Trace WriteLine 在 System Diagnostics 中 然后添加写入文件的跟踪侦听器 本主题来自MSDN展示了一种执行此操作的方法 根据
  • 使用 XHR2 请求而不是 cordova-file-transfer 将二进制数据下载到应用程序沙箱中

    Cordova 正在 日落 即将弃用 cordovan plugin file 请参阅他们的博文 Cordova 开发社区不会再对文件传输插件进行更多工作 如果您愿意 您可以继续使用文件传输插件 在可预见的将来它应该可以正常工作 我们强烈建
  • Python虚拟机需要CPU来执行字节码吗?

    Python虚拟机需要CPU来执行字节码吗 字节码是否转换为机器码 然后CPU参与该过程 为了在任何计算机上运行应用程序 其代码必须始终以某种方式转换为机器代码 然后由 CPU 执行 问题在于这种情况何时以及如何发生 让我尝试向您展示 Py