中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何理解Python虛擬機中的Python運行環境

發布時間:2021-10-27 19:08:58 來源:億速云 閱讀:146 作者:柒染 欄目:編程語言

今天就跟大家聊聊有關如何理解Python虛擬機中的Python運行環境,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

其實Python運行環境是一個全局性的概念,而執行環境實際就是一個棧幀,是Code Block對應的概念,兩者之間存在著本質上的區別,在以后的運行操作過程中就可以了解到他們呢兩者之間的不同。

運行時環境的初始化過程非常地復雜,后面將用單獨的一章來剖析,這里假設初始化的動作已經完成,我們已經站在了Python虛擬機的門檻外,只需要輕輕推動一下***張骨牌,整個執行過程就像多米諾骨牌一樣,一環扣一環地展開。

這個推動***張骨牌的地方在一個名叫PyEval_EvalFramEx的函數中,這個函數實際上就是Python的虛擬機的具體實現,它是一個非常巨大的函數,因此我們在列出其中的源代碼時和以前有些不同。

PyEval_EvalFrameEx首先會初始化一些變量,其中PyFrameObject對象中的PyCodeObject對象包含的重要信息都被照顧到了。當然,另一個重要的動作就是初始化了堆棧的棧頂指針,使其指向f->f_stacktop:

[PyEval_EvalFrameEx in ceval.c]           co = f->f_code;       names = co->co_names;       coconsts = co->co_consts;       ffastlocals = f->f_localsplus;       ffreevars = f->f_localsplus + co->co_nlocals;       first_instr = (unsigned char*)PyString_AS_STRING(co->co_code);       next_instr = first_instr + f->f_lasti + 1;       stack_pointer = f->f_stacktop;       f->f_stacktop = NULL;   /* remains NULL unless yield suspends frame */

前面我們說過,在PyCodeObject對象的co_code域中保存著字節碼指令和字節碼指令的參數,Python虛擬機執行字節碼指令序列的過程就是從頭到尾遍歷整個co_code、依次執行字節碼指令的過程。

Python運行環境的虛擬機中,利用3個變量來完成整個遍歷過程。co_code實際上是一個PyStringObject對象,而其中的字符數組才是真正有意義的東西。這也就是說,整個字節碼指令序列實際上就是一個在C中普普通通的字符數組。因此,遍歷過程中所使用的這3個變量都是char*類型的變量:first_instr永遠指向字節碼指令序列的開始位置;

next_instr永遠指向下一條待執行的字節碼指令的位置;f_lasti指向上一條已經執行過的字節碼指令的位置。展示了這3個變量在遍歷中某時刻的情形:

[ceval.c]   /* Interpreter main loop */   PyObject* PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)   {       ……       why = WHY_NOT;       ……       for (;;) {       ……       fast_next_opcode:           f->f_lasti = INSTR_OFFSET();           //獲得字節碼指令           opcode = NEXTOP();           oparg = 0;           //如果指令需要參數,獲得指令參數           if (HAS_ARG(opcode))               oparg = NEXTARG();      dispatch_opcode:           switch (opcode) {           case NOP:               goto fast_next_opcode;           case LOAD_FAST:               ……           }   }

那么這個一步一步的動作是如何完成的呢,我們來看一看Python運行環境執行字節碼指令的整體架構,其實就是一個for循環加上一個巨大的switch/case結構,熟悉Windows SDK編程的朋友可以想象一下Windows下那個巨大的消息循環,就是那樣的結構。在對PyCodeObject對象的分析中我們說過,Python的字節碼有的是帶參數的,有的是沒有參數的,而判斷是否帶參字節碼是通過HAS_ARG這個宏實現的。

注意,對不同的字節碼指令,由于存在是否需要指令參數的區別,所以next_instr的位移可能是不同的。但是無論如何,next_instr總是指向Python下一條要執行的字節碼,這很像x86平臺上的那個PC寄存器。

Python在獲得了一條字節碼指令和其需要的指令參數后,會對字節碼指令利用switch進行判斷,根據判斷的結果選擇不同的case語句,每一條字節碼指令都會對應一個case語句。在case語句中,就是Python對字節碼指令的實現。

在成功執行完一條字節碼指令后,Python運行環境的執行流程會跳轉到fast_next_opcode處,或者是for循環處,不管如何,Python接下來的動作都是獲得下一條字節碼指令和指令參數,完成對下一條指令的執行。如此一條一條地遍歷co_code中包含的所有字節碼指令,最終完成了對Python程序的執行。

看完上述內容,你們對如何理解Python虛擬機中的Python運行環境有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

平武县| 搜索| 淮北市| 大理市| 宜君县| 晋宁县| 会东县| 西林县| 武陟县| 合作市| 小金县| 通榆县| 东山县| 绵阳市| 泸西县| 安图县| 南通市| 桂东县| 渝中区| 卢龙县| 舒兰市| 武平县| 高邮市| 忻州市| 天台县| 泽州县| 外汇| 图木舒克市| 临清市| 武隆县| 信丰县| 永城市| 建宁县| 晋州市| 忻城县| 铁岭市| 黔东| 保康县| 金秀| 泗水县| 乳源|