python 如何執行

27
Python 如何執行

Upload: kao-kuo-tung

Post on 06-May-2015

1.049 views

Category:

Technology


5 download

DESCRIPTION

How does the python run code?

TRANSCRIPT

Page 1: Python 如何執行

Python 如何執行

Page 2: Python 如何執行

演講經歷

● 2013/04 在 taipei.py 演講關於 pdb 的實作。相關投影片:http://www.slideshare.net/ya790026/recoverpdb

● 2013/05 在 pyconf.tw 演將 CPython 原始碼解析。相關投影片:http://www.slideshare.net/ya790026/c-python-23247730。

Page 3: Python 如何執行

Python 如何被執行

1. 將程式碼編譯成 code object2. 執行 code object 的 byte code,變數等相關

資訊放在 frame object 裡。3. 一個 frame 對應到一個 code object

Page 4: Python 如何執行

code object

● co_name gives the function name; ● co_varnames is a tuple containing the

names of the local variables (starting with the argument names);

● co_consts is a tuple containing the literals used by the bytecode;

Page 5: Python 如何執行

frame object

● f_back is to the previous stack frame (towards the caller), or None if this is the bottom stack frame;

● f_code is the code object being executed in this frame;

● f_locals is the dictionary used to look up local variables;

● f_globals is used for global variables;

Page 6: Python 如何執行

TOS3 TOS4 TOS1 TOS

TOPBUTTON

Stack

Page 7: Python 如何執行

op code

● opcode 定義在 Include/opcode.h● opcode 的長度為一個 byte● opcode 依照參數種類可分為三種

○ 無參數,如 NOP○ 參數來源來自 stack,如BINARY_ADD○ 參數來源來自 opcdoe 後兩個 bype,如

LOAD_CONST● 如果一個函數使用超過 2^16 個常數?

○ 當 opcdoe 的參數來源來自opcdoe 後兩個 bype,而該參數無法以 2 byte 來表示。則在該 opcdoe 前插入 EXTENDED_ARG。該 opcode 的參數為 (EXTENDED_ARG 的參數 <<16 | 該opcdoe 的參數)

Page 8: Python 如何執行

Python Bytecode Instructions

● NOP()Do nothing code. Used as a placeholder

by the bytecode optimizer.● POP_TOP()

Removes the top-of-stack (TOS) item.● ROT_TWO()

Swaps the two top-most stack items.

Page 9: Python 如何執行

Python Bytecode Instructions

Unary Operations take the top of the stack, apply the operation, and push the result back on the stack

● UNARY_POSITIVE()Implements TOS = +TOS.

● UNARY_NEGATIVE()Implements TOS = -TOS.

● UNARY_NOT()Implements TOS = not TOS.

Page 10: Python 如何執行

Python Bytecode Instructions

Binary operations remove the top of the stack (TOS) and the second top-most stack item (TOS1) from the stack. They perform the operation, and put the result back on the stack.

BINARY_POWER()

Implements TOS = TOS1 ** TOS.

BINARY_MULTIPLY()

Implements TOS = TOS1 * TOS.

Page 11: Python 如何執行

Python Bytecode Instructions

Slice assignment needs even an additional parameter. As any statement, they put nothing on the stack.

STORE_SLICE+0()

Implements TOS[:] = TOS1.

STORE_SLICE+1()

Implements TOS1[TOS:] = TOS2.

Page 12: Python 如何執行

Miscellaneous opcodes.

LOAD_FAST(var_num)Pushes a reference to the local co_varnames[var_num] onto the stack.

LOAD_CONST(consti)Pushes co_consts[consti] onto the stack.

BUILD_LIST(count)

Works as BUILD_TUPLE, but creates a list.

Page 13: Python 如何執行

def test(data, data1): a = 5 print 'hello', print data return 1

import disprint dis.dis(test)

Page 14: Python 如何執行

co_consts: (None, 5, 'hello', 1)co_varnames: ('data', 'data1', 'a')

Page 15: Python 如何執行

2 0 LOAD_CONST 1 (5) 3 STORE_FAST 2 (a) 3 6 LOAD_CONST 2 ('hello') 9 PRINT_ITEM 4 10 LOAD_FAST 0 (data) 13 PRINT_ITEM 14 PRINT_NEWLINE 5 15 LOAD_CONST 3 (1) 18 RETURN_VALUE

Page 16: Python 如何執行

def test():print 'hello', print 'hello',

import disprint dis.dis(test)

Page 17: Python 如何執行

2 0 LOAD_CONST 1 ('hello') 3 PRINT_ITEM

3 4 LOAD_CONST 1 ('hello') 7 PRINT_ITEM 8 LOAD_CONST 0 (None) 11 RETURN_VALUE

Page 18: Python 如何執行

def printf1(name, **kwargs): print kwargs[name]code = printf1.func_code

import disprint dis.dis(code)

Page 19: Python 如何執行

8 0 LOAD_FAST 1 (kwargs) 3 LOAD_FAST 0 (name) 6 BINARY_SUBSCR 7 PRINT_ITEM 8 PRINT_NEWLINE 9 LOAD_CONST 0 (None) 12 RETURN_VALUE

Page 20: Python 如何執行

def test1():a = 1b = 2c = a + bd = a * b

def test2():a, b = 1, 2c, d = a + b, a * b

Page 21: Python 如何執行

5 0 LOAD_CONST 1 (1) 3 STORE_FAST 0 (a)

6 6 LOAD_CONST 2 (2) 9 STORE_FAST 1 (b)

7 12 LOAD_FAST 0 (a) 15 LOAD_FAST 1 (b) 18 BINARY_ADD 19 STORE_FAST 2 (c)

8 22 LOAD_FAST 0 (a) 25 LOAD_FAST 1 (b) 28 BINARY_MULTIPLY 29 STORE_FAST 3 (d) 32 LOAD_CONST 0 (None) 35 RETURN_VALUE

Page 22: Python 如何執行

11 0 LOAD_CONST 3 ((1, 2)) 3 UNPACK_SEQUENCE 2 6 STORE_FAST 0 (a) 9 STORE_FAST 1 (b)

12 12 LOAD_FAST 0 (a) 15 LOAD_FAST 1 (b) 18 BINARY_ADD 19 LOAD_FAST 0 (a) 22 LOAD_FAST 1 (b) 25 BINARY_MULTIPLY 26 ROT_TWO 27 STORE_FAST 2 (c) 30 STORE_FAST 3 (d) 33 LOAD_CONST 0 (None) 36 RETURN_VALUE

Page 23: Python 如何執行

PyEval_EvalFrameEx

● Python/ceval.c● 負責解讀 opcdoe 並呼叫對應的動作

Page 24: Python 如何執行

BINARY_ADD

1. 都是整數的話,直接相加2. 都是字串的話,呼叫 string_concatenate3. 不滿足上面條件,則呼叫 PyNumber_Add ( in

Object/typeobject.c)。他會去呼叫 __add__4. 從 stack 取得兩個參數,放回一個結果

Page 25: Python 如何執行

結論

1. 比較長的程式碼,op code 未必比較長2. python 是一個程式碼大量重用的程式

Page 26: Python 如何執行

Olis

● http://www.olis.com.tw

Vira: 一切渴望再度成為可能

http://viraapp.co

再看看看! - 免費簡易型防偷窺APP