閱讀472 返回首頁    go 阿裏雲 go 技術社區[雲棲]


[筆記]Python虛擬機對創建基本內置對象的執行過程

同樣的,有demo.py代碼如下:
i = 1
s = "Python"
d = {"1":1, "2":2}
l = [2, 3]

有test.py代碼如下:
import dis

source = open('./demo.py').read()
co = compile(source, './demo.py', 'exec')

dis.dis(co)

輸出如下:
  1           0 LOAD_CONST               0 (1)
              3 STORE_NAME               0 (i)

  2           6 LOAD_CONST               1 ('Python')
              9 STORE_NAME               1 (s)

  3          12 BUILD_MAP                2
             15 LOAD_CONST               0 (1)
             18 LOAD_CONST               2 ('1')
             21 STORE_MAP           
             22 LOAD_CONST               3 (2)
             25 LOAD_CONST               4 ('2')
             28 STORE_MAP           
             29 STORE_NAME               2 (d)

  4          32 LOAD_CONST               3 (2)
             35 LOAD_CONST               5 (3)
             38 BUILD_LIST               2
             41 STORE_NAME               3 (l)
             44 LOAD_CONST               6 (None)
             47 RETURN_VALUE  

這裏需要討論的就是字典和列表的創建。

對於d = {"1":1, "2":2}這一語句,Python虛擬機首先是執行BUILD_MAP:
        case BUILD_MAP:
            x = _PyDict_NewPresized((Py_ssize_t)oparg);
            PUSH(x);
            if (x != NULL) continue;
            break;

接著把鍵值對壓棧,然後執行STORE_MAP:
        case STORE_MAP:
            w = TOP();     /* key */
            u = SECOND();  /* value */
            v = THIRD();   /* dict */
            STACKADJ(-2);
            assert (PyDict_CheckExact(v));
            err = PyDict_SetItem(v, w, u);  /* v[w] = u */
            Py_DECREF(u);
            Py_DECREF(w);
            if (err == 0) continue;
            break;

因為剛才把鍵值對壓棧了,所以現在棧頂是key,第二個是value,第三個是字典對象,棧指針-2,然後把鍵值對放入字典對象中。
接著再插入一個鍵值對,然後執行STORE_NAME,把字典對象d放入局部符號表中。

對於l = [2, 3]這一語句,Python虛擬機先是把兩個元素壓棧,然後執行BUILD_LIST,攜帶參數2:
        case BUILD_LIST:
            x =  PyList_New(oparg);
            if (x != NULL) {
                for (; --oparg >= 0;) {
                    w = POP();
                    PyList_SET_ITEM(x, oparg, w);
                }
                PUSH(x);
                continue;
            }
            break;

Python虛擬機根據命令參數決定出棧多少個元素放入列表中,最後一樣是把列表對象l出棧,放入局部符號表中。

最後更新:2017-04-02 22:16:33

  上一篇:go 您的設計模式,我們的設計模式 java設計模式
  下一篇:go 自定義menu替代TabHost中的TabWidget