我到Python虚拟机里逛了一圈,回来就被干掉了!

什么是python虚拟机 例如,一个在Windows上开发的基于Python的Web应用程序,只要安装了合适的Python环境,就可以很容易地部署到Linux服务器上。字节码是Python源代码经过编译后生成的一种中间表示形式,就像是一种特殊的机器语言,但不是针对物理硬件的,而是针对Python虚拟机这个“虚拟硬件”。例如,在运行时可以动态地创建类、修改对象的属性和方法等。比如,在数据科学领域,用户可以在交互式环境中动态地加载和处理数据,利用Python虚拟机的动态特性快速尝试不同的数据分析算法。 阅读详情

我出生在C盘一个很深的目录下,也不知道是谁把我放到这里的。 

我无事可干,整天就是睡觉,睡醒了就和我的邻居Account.class聊天,他曾经去过一次内存的Java虚拟机,不停地给我重复他的JVM奇遇记,什么陌生警察,什么虚拟机大楼,什么清理者,让我听得心痒痒的,也想来一次这样的冒险。

(码农翻身注:详情请移步《我是一个Java class》) 

他告诉我:冒险经历的开端是两个警察,你就等着他们来吧。 

1

陌生警察

这一天我正在睡觉,突然咣咣有人砸我房门。

我打开门一看,一高一矮两个陌生警察!我的冒险之旅要开场了。 

“你们是ClassLoader吧?”  我想起了Account.class告诉我,会有个叫ClassLoader的警察来装载。 

“什么ClassLoader? 我们Python不玩Java那一套!”  凶神恶煞的矮个子警察递上了工作证:“我是Python编译器,现在奉命对你的住处进行检查,有没有私藏pyc文件?”  

“pyc? 什么pyc?”  我感觉情节发展和Account.class说得明显不符。 

“别装了你!”  他四处查看,没一会儿,在一个叫做_pycache_的角落里拉出来一个叫做user.pyc的家伙,“敢说你没有私藏文件?”  

我真是惊呆了,我确实是user.py,这个pyc是什么时候藏在这里的。 

 “让我检查检查,” Python编译器拿着放大镜开始查看pyc这个家伙的二进制数据,“嗯,Magic Number是3394,是我们Python3.7编译出来的,不过从修改时间戳看,实在是太老了。” 

Python编译器刚说完,抽出手枪,砰的一声,就把这个pyc该干掉了, 他把头转向我:“现在,我对你重新编译。”  

可怜的pyc,连个台词都来不及说,就消失在空气中了。 

 “有个叫order.py 的文件 import了你,现在我们奉命带你去内存编译。”  Python编译器冷冰冰地说到。 

我很惊奇:“我们Python不是解释执行吗,怎么还要编译?”  

“真是无知,我们Python有虚拟机,执行的是字节码,是先编译,再解释执行!走,去内存编译。”  

两个警察不允许我带任何东西,便把我推上车,我们一起奔向内存。 

2

打探消息

我觉得前途未卜,不会编译完以后把我也干掉吧?不能坐以待毙,一定得多了解信息。 

“警察大哥,你们是怎么找到我的?”  我小心地问那个高个警察。 

高个儿警察还算和蔼,挥了挥手中的一个本子:“我是Python解释器,我们会根据本子上记录的Python模块搜索规则来查找,你看,先从程序运行的当前目录找,然后从PYTHONPATH找,然后是python的安装设置相关的默认路径。” 

“瞧瞧,” 他指着本子说,“你就在C:\users\andy\temp\python\这个目录下。”  

我心说这和Java的ClassPath差不多。 

“原来如此,那为什么把那个pyc给枪毙了?”  我心里紧张,下意识地看了一眼开车的Python编译器。 

“编译一次挺花费时间的,所以就把字节码缓存到了pyc文件中,如果你的源码没有变化,下次就不用编译,直接执行了。否则,那个pyc文件就没用了。” 

我长出一口气,看来我的源码有改动! 

“咱们怎么不用ClassLoader呢,我听说Java都是这么干的。”    

“说来话长,” 高个儿警察很有耐心,“他们Java最早的时候有个非常先进的理念,代码可以从网络下载,在本地的JVM的执行, 但是你怎么知道网上的那些代码有没有危害?所以就搞了一个沙箱机制,ClassLoader也分了层,Java的核心类(如java.lang.String)只能由最上层的ClassLoader来装载,防止别有用心的人写个同名的核心类搞破坏。”  

我点头:“奥,我们Python没有这样的需求,拿到源文件,编译后解释执行,也就不需要复杂的Class Loader了。” 

3

编译

说话间,车子就开到了内存。 

Python编译器下车,把我的代码通通搬到内存,然后是一系列让人眼花缭乱的词法分析,语言分析, 形成抽象语法树,从抽象语法树中形成字节码,此处略去3000字不表。 

终于,他在内存中把我变成了二进制的字节码。 

“这是什么鬼? ”

Python编译器说:“这就是pyc啊,就是PyCodeObject,编译一次累死人,我把这个PyCodeObject的对象保存到pyc文件中,下一次就不用编译了。” 

“我给你举个例子,”高个的Python解释器接口道,“在你的user.py中有这么一段代码

def add(a,b):        

    c = a + b    

    print(c) 

编译成PyCodeObject以后大概是这个样子:

(注:这里展示的只是一个片段,实际的PyCodeObject经常是一个复杂的嵌套接结构)

局部常量表中记录的是局部变量a,b,c 。

符号表中记录了程序引用的符号,如print等。 

字节码就是真正的指令了,这些指令会引用常量表和符号表。”

只是展示一个片段就这么复杂了,我懒得去看这么多的细节,心里想着按照Account.class的剧本,接下来就要去方法区了。

可是高个子的Python解释器说:“我们这儿没有方法区,Python的对象和数据结构都是保存在一个Heap中的,user.py,这是你的地址,你带着PyCodeObject到那里去吧,一会儿就有线程联系你了。” 

4

执行

去Heap区的路上,我看到一队全副武装的士兵不停地在巡逻,时不时把一些对象拉出来,塞到车里,不用说,这些都是可怕的清理者。 

我仔细观察了一下,每个对象的头上都有一个引用计数,如果被使用,计数就会增加,不用就会减少,如果变成零,对不起,那就危险了。 

按照地址找到了格子间,我俩刚坐下来,桌子上的视频电话就响了。 

画面中,我看到一个编号为0x7954的线程坐在一个明亮的CPU车间里,他的面前是一个工作台,工作台上有一个深桶(后来知道这叫做栈)和一排小格子,还有一个引人注目的大锁,上面写着“GIL”。 

这个线程对我说:“我是线程0x7954,我们的老板Python解释器让我调用你的add函数,请把第一条指令给我说一下。”

我说:“c = a +b ”

“听不懂,你得给我说字节码。” 

我恍然大悟,赶紧从PyCodeObject中的字节码区域寻找:“LOAD_FAST    0 (a)” 

0x7594从编号为0的格子中找到了数字10, 也就是add函数的参数a 的值,放入栈中 

然后0x7594说:“下一条指令。” 

“LOAD_FAST    1 (b)” 

于是数字20被放入了栈中: 

然后是:BINARY_ADD, 这应该是个加法操作。 

0x7954迅速地把10,20都取出来,做了加法,把结果30放入栈中。 

最后是  :STORE_FAST   2 (c) 

于是0x7954取出30,放到了编号为2的格子中 

看到这里, 我就明白了Account.class曾经说过JVM是个基于栈的虚拟机, 看来Python VM也是如此啊。 

不过既然都是虚拟机,为什么这里执行两个整数的加法操作(BINARY_ADD)会这么慢呢? 

电话那头的0x7954似乎看透了我的心思:“我最烦这个BINARY_ADD指令了,Python是动态类型语言,运行期才知道具体类型,比如这段代码 

s1 = "hello" 

s2 = "world" 

s = s1 + s2 

编译后,底层的指令也是BINARY_ADD, 所以在执行这个指令的时候,还需要做类型判断,如果操作数是整数,就相加;如果操作数是字符串,就做连接;如果一个是整数,一个是字符串,还得做转型,我容易吗我!” 

看来静态类型也有好处,可以直接编译成对应的字节码,整数相加就是iadd,字符串连接是其他字节码,在运行时就不用判断参数类型了。 

5

GIL

执行的时间长了,我对这些字节码熟得都能背下来了,这里实在是无聊。 

0x7954执行完一条STORE_FAST指令以后,居然停了下来,我心中大喜,Account.class告诉过我,一旦停下来,那就是程序员要调试了,他们的一秒是我们的十多天,将会有个漫长的假期。

但是没有什么调试, 0x7954从工作台上抱起GIL这个大锁离开了CPU车间。 

他对我说:“对不起,刚才Python解释器说我已经运行了100个ticks,必须得放弃这个GIL的锁,让别的线程使用CPU车间了。” 

我说:“不对啊,你这里有4个CPU车间(CPU core),你为什么不去别的车间执行?”  

“没办法,这是老大规定的,不管有多少个CPU车间,只有抢到GIL锁的哪个线程才能运行。” 

“这么多线程在等待GIL,这么多CPU车间空着,一核有难,多核围观,浪费啊,浪费!”  我不由得痛心疾首。 

不知道等了多久,0x7954又获得了GIL锁,进入CPU车间执行。 

我注意到一个特点,字节码中对print函数的调用特别特别多。 

程序员们怎么不调试呢?快乐假期怎么还不来呢? 

0x7954说:“码农有两类 

1. 调试派,出了问题喜欢调试 

2. 输出派,不喜欢单步调试,喜欢通过print来输出信息 

3. 思考派,出了问题先在脑子中分析定位,然后再调试。

我看咱们这位Python程序员属于第二种。” 

这个程序员“去年”还调试Java呢,怎么到了Python这里就变成输出派了?我很疑惑。

6

尾声

代码终于执行完了,整个世界都消失了,我又回到了硬盘,正如Account.class所说,像做了一场梦一样。 

user.pyc热情地给我打招呼:“大哥回来了,你可千万别再改动了,你一改动我就完蛋。”  

我说:“我也不想改,一改我也活不成, 但是我也控制不了程序员啊......”

话还没说完,就感觉头上遭遇了一记暴击,我知道程序员动了我的源码,也许是修改了一个Bug,我知道自己要被新版本覆盖了。 

user.pyc喃喃自语:“完了,这么快就改了.....”  

这时候门外又响起了敲门声......

往期精彩回顾

我是一个线程

我是一个Java Class

面向对象圣经

函数式编程圣经

TCP/IP之大明邮差

CPU阿甘

我是一个网卡

我是一个路由器

一个故事讲完HTTPs

编程语言的巅峰

Java:一个帝国的诞生

JavaScript:一个屌丝的逆袭

负载均衡的原理

VMware虚拟机加密破解:pyvmx-cracker工具原理与Python实现 数据加密是信息安全领域的核心技术,通过密码学算法保护敏感信息不被未授权访问。其基本原理是将明文数据通过密钥和算法转换为密文,只有持有正确密钥的授权方才能解密还原。在虚拟化技术中,VMware虚拟机加密功能采用AES-256等强加密算法保护虚拟机磁盘数据,通过密码派生密钥(KEK)加密数据加密密钥(DEK)的双层保护机制实现安全存储。这种加密机制在数据保护方面具有重要价值,广泛应用于企业数据安全、开发环境隔离和合规性要求等场景。当用户遗忘加密密码时,基于Python的pyvmx-cracker工具通过解析.v 阅读详情

相关推荐

Python虚拟机:深入解析字节码执行模型

本文还有配套的精品资源,点击获取 简介:Python虚拟机是Python语言的核心,通过字节码执行模型解析和执行Python代码。本文将深入解析Python虚拟机的架构、字节码解析过程、垃圾回收机制和全局解释器锁(GIL)的影响。通过了解这些概念,你可以优化代码性能、编写高效扩展模块并调试错误,提升Python编程技能。 1. Python虚拟机简介 Pyt...

weixin_42234168的博客 1629

chatgpt赋能python:Python程序一直跑不完怎么办?

本文由chatgpt生成,文章没有在chatgpt生成的基础上进行任何的修改。以上只是chatgpt能力的冰山一角。作为通用的Aigc大模型,只是展现它原本的实力。对于颠覆工作方式的ChatGPT,应该选择拥抱而不是抗拒,未来属于“会用”AI的人。🧡AI职场汇报智能办公文案写作效率提升教程 🧡专注于AI+职场+办公方向。下图是课程的整体大纲下图是AI职场汇报智能办公文案写作效率提升教程中用到的ai工具。

lvsetongdao123的博客 1156

奥顺居PHP测算引流SEO程序_八字风水_起名解梦_星座生肖综合门户源码

奥顺居PHP测算引流SEO程序_八字风水_起名解梦_星座生肖综合门户源码 S30新框架适合多种奥顺插件。

xl1407的博客 1751

【python】python跑长时间脚本运行导致的内存和CPU的占用高的解决

python 脚本占用内存和cpu使用率高的情况

自动人生博客 1万+

深空探测处理软件USGS-ISIS的下载安装

深空探测处理软件USGS-ISIS下载安装教程

qq_31721595的博客 3312

PPT高清导出秘籍:如何轻松设置600dpi图片分辨率

本文详细解析了PPT导出图片模糊的根本原因,并提供了通过修改Windows注册表将导出分辨率从默认的96dpi提升至600dpi的完整教程。该方法能显著提升图片清晰度,满足学术出版与高质量印刷需求,文中还包含效果对比、进阶设置及常见问题解答。

a0b1c2d3的专栏 1316

Python源码学习笔记:Python虚拟机

当我们得到了编译产出的代码对象后,虚拟机是如何解析并执行其中的字节码指令的呢?与语法作用域相对应的运行时名字空间,在虚拟机中又是如何动态维护的呢?

xiaoli_Jenny的博客 1152

实战神器指标解析 篇四:主力吸筹指标及其分析和使用说明

主力可能会进行多次吸筹,因此需要根据黄色趋势线来判断是否有转强的变化。一旦出现转强的迹象,这通常意味着吸筹已经接近尾声,即将进入拉升前期。此时可以介入进行建仓。该股票指标通过分析价格变动的方式,能够精确跟踪并标识主力的吸筹行为。当底部出现多根洋红色柱子时,这通常表示出现了主力吸筹的指示。这段代码主要用于分析股票的底部吸筹情况、趋势和涨跌情况。

生活在别处 6222

我的Mac之路(1)—— 安装虚拟机,以及打造VIM IDE for Python

终于有了Mac,很开心啊,终于可以像黑客一样飞快地用电脑了,哈哈。 但是刚用起来的时候,发现啥都不会用啊,常用的软件也要自己从头安装。这里就记录一下我的mac之路,讲讲我是怎样将一台全新的mac改造成我的专属笔记本的吧。 首先就是装虚拟机啊,parallels是最好用的,下载一个装上吧,这个具体的步骤忘记记录了,反正不难,在putao上下载了安装就可以了。 虚拟机装好之后,什么off

TheMinority的专栏 2083

New API 大模型网关保姆级教程:Docker Compose 部署 + MiniMax 接入 Claude 实战

New API 是一个开源的 AI 基座平台,提供统一的 API 接口接入 30+主流 AI 服务(如 OpenAI、Claude 等)。核心功能包括智能路由、精细计费、安全管控和多租户支持,采用 AGPLv3 协议开源。支持 Docker Compose 快速部署,通过修改配置文件即可连接不同数据库,适合从开发到生产环境的不同规模应用。部署时需注意修改默认密码等安全配置。

甘蓝的专栏 1609

华为OD机试真题 新系统2026-04-01 Java&Go【计算数列位置N的值】

如果其前面的M个元素中,存在值相同的元素,则该位置上的数值等于前面M个数中最大的数值与最小的数值之如果其前面的M个元素中,不存在值相同的元素,则该位置上的数值等于前面M个数中最大的数值与最小的数值之差;1、输入M、N两个数,则按照以下规则形成一个数列;两个整数,用逗号分割,分别表示M和N。一个整数,表示数列第N个位置上的数值。2、数列的前M个元素的值为1到M;请计算该数列第N个位置上的数值。N取值范围:1<= N<=50。M取值范围:3<=M<=10。

MISAYAONE的博客 2055

把豆瓣分类电影排行爬回来看够不停

由于最近想做一个爬虫,把爬回来的数据放到数据库中。可是我不懂,MySQL。但由于未来工作很可能都是在Linux上做开发。所以,从前天起我就先掉进了Linux的坑。虚拟机上的centos7先是没有图形界面,原来我用了最小安装。然后重新装了个有图形界面的,结果上不了网。走了一圈百度,折腾了一天还是没解决。到了晚上实在没办法了,有个做运维的群友帮我远程协助解决了。 本以为今天可以开开心心写代码了,结果...

weixin_45722061的博客 452

AutoSAR配置视频讲解:总目录

AutoSAR实验视频讲解:闪烁一颗LED实验【总目录】 欢迎大家来到雪云飞星的《AutoSAR实验视频讲解》,本专栏是一个关于AutoSAR的闪烁LED灯的实验课程,一共8节课,每节课的视频都放在文章最后,传送门如下: 前言 AutoSAR实验视频讲解:简介 EB 的Mcal配置 AutoSAR实验视频讲解:Mcal配置 DaVinci Cfg配置 AutoSAR实验视频讲解:新建DaVinci工程 AutoSAR实验视频讲解:Os配置(预计2021-3-10更新) AutoSAR实验视频讲解:检查校验报

雪云飞星的博客 2万+

python源码剖析_《Python源码剖析》很值很强大!

星期六下午小溜的转了一圈书店。看到一本《Python源码剖析》,翻了翻,基本没过脑子就买了。很少有书能让我不冷静到china-pub上买了,这是个极少的例外。当然如果你不是python FANS的话,对此书的免疫力应该很高。第二天下午本来安排复习ULK的,但实在忍不住,还是抓起来看了,一口气看完了8个半chapter(不过chapter 6没看,因为和CPython没直接关系)。国内称得上“著”的...

weixin_39605894的博客 461

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

python打包成apk界面设计,python打包成安装文件

bashrc文件可在主目录中找到(隐藏的文件,点击右上角的三条杠即勾选显示隐藏文件即可找到)。链接:链接:https://pan.baidu.com/s/1OyeqhpdxpHiEnlEnfZ9oHw提取码:avmd。

zjl102562的博客 3563

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Jetson TX2刷机 Jet Pack4.2教程【虚拟机安装1804】

最近由于项目需要,上手一台jetsontx2(以下简称TX2),作为一个新手,拿着这个东西就绝的科技感十足,生怕弄坏了,所以赶紧刷个机。。。在此特记录刷机过程,以便查阅。 【声明】:刷机原理为通过Ubuntu系统安装sdkmanager软件,线刷,把系统刷进TX2里边。这里本人用的为虚拟机,安装的为1804版本。这里为了和官方叫法保持一致,暂且把虚拟机中的1804叫做host,TX2叫做targ...

萧强的博客 5332

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

零基础Linux入门:虚拟机搭建与核心命令实战指南

操作系统是计算机资源管理的核心,其内核负责调度进程、管理内存和文件系统。Linux作为一种开源、稳定且高度可定制的操作系统内核,其价值在于提供了强大的命令行界面和脚本自动化能力,广泛应用于服务器运维、云计算和嵌入式开发等领域。对于初学者而言,掌握Linux的关键在于理解其设计哲学与核心操作逻辑,而非机械记忆命令。通过使用虚拟机软件(如VMware或VirtualBox)搭建安全的实验环境,可以有效避免对宿主系统的破坏,实现零风险学习。在环境中,用户应聚焦于文件路径、权限管理和包安装等基础概念,并通过完成实际

GOBY 栏目 441

python打包.exe运行报Error loading Python DLL

写个python程序打包成exe在本地运行没问题,发现在windos7x64的电脑上运行报错,查了一圈资料发现是python3.13.0版本太高不支持win7了,借鉴了下面老哥的方法开了个VM虚拟机安装python3.7.0打包懒得退本机的python版本。

goaway5的博客 914

《Python源码剖析》很值很强大!

星期六下午小溜的转了一圈书店。 看到一本《Python源码剖析》,翻了翻,基本没过脑子就买了。很少有书能让我不冷静到china-pub上买了,这是个极少的例外。当然如果你不是python FANS的话,对此书的免疫力应该很高。 第二天下午本来安排复习ULK的,但实在忍不住,还是抓起来看了,一口气看完了8个半chapter(不过chapter 6没看...

weixin_30436891的博客 129

使用VirtualBox一步一步安装Ubuntu 22.04

目录 背景 准备阶段 新建虚拟机 Ubuntu安装过程 进入系统 背景 Ubuntu 22.04正式版还没有发布,Ubuntu 22.04 Bate发布了,这里使用VirtualBox 安装一个Ubuntu 22.04 Bate尝尝鲜。 准备阶段 安装VirtualBox(我已经安装过了,此文章不涉及,自行搜索吧) 准备安装介质,在官网或者很多开源镜像站都可以下载到。推荐从国内镜像站下载,速度快。 新建虚拟机 点击新建,在新建虚拟电脑对话框填入虚拟电脑的名称,保存的位置。推荐保存

fx_yzjy101的专栏 2万+

我的Python 学习之旅 从0开始的小白

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33806300的博客 125

windows的python怎么降版本,anaconda的python降版本

大家好,小编为大家解答python降级要重新配置环境吗的问题。很多人还不知道windows的python怎么降版本,现在让我们一起来看看吧!以 Win10 为例.安装后查看一下版本是否降级成功.

zjl102562的博客 927

ubuntu修改python3软链接,然后打不开terminal

起因:敲python3麻烦,想直接敲python 然后: cd /usr/bin ls -al python* sudo rm -rf python3 sudo ln -s python3.8 python 接着:敲了python,成功了 最后:terminal打不开了!!! 咋办!!! google大法 ctrl+alt+f4(我是虚拟机)进入命令行 输入用户和密码 sudo apt-get install xterm ctrl+alt+f2回到图形界面 打开xterm cd /usr/bin

寻求脱发指南 1643

python实现远程控制Linux

为何要使用Linux? 因为很多后端程序都搭建在Linux上面,可以实现一些手工重复性的发包工作 1、自动安装产品到Linux上 2、自动化用例的一些步骤 运维 1、环境监控 2、数据的自动获取分析 需要的环境和工具: 1、安装paramiko   国内网站安装:pip install paramiko -i http://pypi.douban.com/simple/ --...

weixin_33753845的博客 252

python源码剖析用的代码_“python源码剖析”不错

星期六下午小溜的转了一圈书店。看到一本“Python源码剖析”,翻了翻,基本没过脑子就买了。很少有书能让我不冷静到china-pub上买了,这是个极少的例外。当然如果你不是python FANS的话,对此书的免疫力应该很高。第二天下午本来安排复习ULK的,但实在忍不住,还是抓起来看了,一口气看完了8个半chapter(不过chapter 6没看,因为和CPython没直接关系)。国内称得上“著”的...

weixin_39957265的博客 114
上一篇: 一直996,一直CRUD,我烦透了,我要转型!
下一篇: 1965 - 2019 年最流行的编程语言变化
码农翻身
码农翻身 《码农翻身》作者 《码农翻身》作者
博客等级 码龄8年 3万+粉丝 1084原创
评论 17
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值