# Python pycæ ¼å¼åæ
> è¿ç¯æç« åªæ¯çº¯ç²¹åæpython pycæä»¶æ ¼å¼ï¼ä¸»è¦æ¯å
³äºpyc卿件ä¸çå卿¹å¼è¿è¡äºè§£æãpycæ¯pythonåèç 卿件ä¸åå¨çæ¹å¼ï¼èå¨èææºè¿è¡æ¶ç¯å¢ä¸å¯¹åºPyCodeObject对象ãå
³äºPyFrameObject以åPyFunctionObjectçè¿è¡æ¶ç»æï¼åç»å¸æå¦ä¹ éå½»äºè½å¤ä¸å¹¶åæã
## 1.ç¤ºä¾æä»¶
æºæä»¶test.py
```
s = "hello"
def func():
a = 3
print s
func()
```
éè¿æ§è¡```python pyc_generator.py test``` å¯ä»¥çæç¼è¯å¥½çpycæä»¶ã
```
##pyc_generator.py
import imp
import sys
def generate_pyc(name):
fp, pathname, description = imp.find_module(name)
try:
imp.load_module(name, fp, pathname, description)
finally:
if fp:
fp.close()
if __name__ == "__main__":
generate_pyc(sys.argv[1])
```
å¾å°test.pycåï¼æ§è¡```hexdump -C test.pyc```å¯ä»¥å¾å°å¦ä¸äºè¿å¶å符æµã
```
00000000 03 f3 0d 0a f6 e9 38 55 63 00 00 00 00 00 00 00 |......8Uc.......|
00000010 00 01 00 00 00 40 00 00 00 73 1a 00 00 00 64 00 |[email protected].|
00000020 00 5a 00 00 64 01 00 84 00 00 5a 01 00 65 01 00 |.Z..d.....Z..e..|
00000030 83 00 00 01 64 02 00 53 28 03 00 00 00 74 05 00 |....d..S(....t..|
00000040 00 00 68 65 6c 6c 6f 63 00 00 00 00 01 00 00 00 |..helloc........|
00000050 01 00 00 00 43 00 00 00 73 0f 00 00 00 64 01 00 |....C...s....d..|
00000060 7d 00 00 74 00 00 47 48 64 00 00 53 28 02 00 00 |}..t..GHd..S(...|
00000070 00 4e 69 03 00 00 00 28 01 00 00 00 74 01 00 00 |.Ni....(....t...|
00000080 00 73 28 01 00 00 00 74 01 00 00 00 61 28 00 00 |.s(....t....a(..|
00000090 00 00 28 00 00 00 00 73 1e 00 00 00 2f 55 73 65 |..(....s..../Use|
000000a0 72 73 2f 73 73 6a 2f 50 72 6f 67 2f 70 79 74 68 |rs/ssj/Prog/pyth|
000000b0 6f 6e 2f 74 65 73 74 2e 70 79 74 04 00 00 00 66 |on/test.pyt....f|
000000c0 75 6e 63 03 00 00 00 73 04 00 00 00 00 01 06 01 |unc....s........|
000000d0 4e 28 02 00 00 00 52 01 00 00 00 52 03 00 00 00 |N(....R....R....|
000000e0 28 00 00 00 00 28 00 00 00 00 28 00 00 00 00 73 |(....(....(....s|
000000f0 1e 00 00 00 2f 55 73 65 72 73 2f 73 73 6a 2f 50 |..../Users/ssj/P|
00000100 72 6f 67 2f 70 79 74 68 6f 6e 2f 74 65 73 74 2e |rog/python/test.|
00000110 70 79 74 08 00 00 00 3c 6d 6f 64 75 6c 65 3e 01 |pyt...., None)
In [42]: co.co_names
Out[42]: ('s', 'func')
In [38]: dis.dis(co)
1 0 LOAD_CONST 0 ('hello') #å°co.co_consts[0]å³'hello'åæ
3 STORE_NAME 0 (s) #以co.co_names[0]ä½ä¸ºkeyï¼å°'hello'åºæ ï¼ç¶å设置f->f_locas['s'] = 'hello'
3 6 LOAD_CONST 1 () ##å°co.co_consts[1]å³funcçåèç 对象åæ
9 MAKE_FUNCTION 0 ##åå»ºå½æ°å¯¹è±¡å¹¶åæ
12 STORE_NAME 1 (func) #f->f_locals['func']=彿°å¯¹è±¡
7 15 LOAD_NAME 1 (func) #å°f->f_locals['func']å³å½æ°å¯¹è±¡åæ
18 CALL_FUNCTION 0 #è°ç¨å½æ°ï¼å¨æ°æ 帧æ§è¡
21 POP_TOP ##彿°è¿åå¼åºæ
22 LOAD_CONST 2 (None) ##Noneåæ
25 RETURN_VALUE ##è¿åNone
```
æç¶æ¯æ£å¥½26个åèï¼å
¶ä¸å
容åå«å¯¹åºè¿äºæä»¤ï¼å
¶ä¸ç¬¬ä¸åæ¯å¨æºç ä¸çè¡æ°ï¼ç¬¬äºåæ¯è¯¥æä»¤å¨co_codeä¸çåç§»ï¼ç¬¬ä¸åæ¯opcodeï¼å为ææä½æ°åæ æä½æ°ä¸¤ç§ï¼æ¯ä¸ä¸ªåèçæ´æ°ã第å忝æä½æ°ï¼å 两个åèã
é£ä¹è¿äºæä»¤å¯¹åºçå°±æ¯æä»¬çå°çpycæä»¶ä¸çå
容äºï¼å
·ä½æä¹åè§ä»£ç ä¸ç注éãLOAD_CONSTæä»¤ä¸º0x64ï¼ç¶å两个åèæä½æ°æ¯0.æ¥ä¸æ¥æ¯STORE_NAMEæä»¤0x5aï¼æä½æ°æ¯0.å
¶ä»ä»¥æ¤ç±»æ¨ï¼frameç¸å
³å
容åé¢åè§£æã
æ¥ä¸æ¥ä»0x28å¼å§æ¯co.co_constså
å®¹ï¼æä»¬ç¥éè¿æ¯ä¸ä¸ªPyTupleObject对象ï¼ä¿åçcode blockç常éï¼å¦å¨åé¢çå°ç飿 ·ï¼æä»¬ç¥é宿3个å
ç´ ï¼å嫿¯å符串helloï¼code object对象func以åNoneãé£ä¹PyTupleObjectè·PyListObject类似ï¼é¦å
æ¯è®°å½ç±»åæ 示TYPE_TUPLEï¼å³'(',ä¹å°±æ¯0x28äºãæ¥ä¸æ¥4个åèæ¯é¿åº¦ï¼è¿éæ¯3表示æ3个å
ç´ ãç¶åæ¯å
ç´ å
容ï¼ç¬¬ä¸ä¸ªæ¯'helloâ,宿¯PyStringObject对象ï¼å æ¤ï¼å
åå
¥æ è®°TYPE_INTERNED,å³'t'ï¼ä¹å°±æ¯ä¸é¢ç0x74äºï¼ç¶åå¢ï¼æ¯åå
¥4个åèçé¿åº¦ï¼å
±5个åèï¼æä»¥è¿æ¯5ï¼æ¥çå°±æ¯helloè¿5个åèã
第äºä¸ªæ¯code objectï¼å¥½å§ï¼è¿ä¸ªå°±ç¸å½äºè·ä¹åçæµç¨åæ¥ä¸éäºã
0x63è·ä¹åç䏿 ·æ¯TYPE_CODEçæ ç¤º'c'ï¼ç¶åå°±æ¯code objectçåä¸ªåæ®µäºãè¿æ¯æ¥ä¸éï¼åå«å¦ä¸
First Header | Second Header
------------ | -------------
co_argcount | 0
co_nlocals | 1
co_stacksize | 1
co_flags | 67
co_code | æ 示0x73ï¼å³TYPE_STRINGãé¿åº¦0x0fï¼å³15个åèé¿åº¦ãç¶åä»0x64å¼å§å°±æ¯co_codeå
容ã
ä¸é¢åæä¸funcçco_codeï¼é¦å
çä¸disçç»æ:
```
In [63]: func.co_nlocals
Out[63]: 1
In [64]: func.co_consts
Out[64]: (None, 3)
In [65]: func.co_names
Out[65]: ('s',)
In [66]: func.co_varnames
Out[66]: ('a',)
In [62]: dis.dis(func)
4 0 LOAD_CONST 1 (3) #å°func.co_consts[1]å³3åæ
3 STORE_FAST 0 (a) #åå¨3å¨åéaä¸
5 6 LOAD_GLOBAL 0 (s) #åå
¥å
¨å±åés
9 PRINT_ITEM ##æå°s
10 PRINT_NEWLINE ##æå°æ¢è¡
11 LOAD_CONST 0 (None) #Noneåæ
14 RETURN_VALUE ##彿°è¿åNone
```
æ¥ä¸æ¥å°±æ¯funcçco_constsåæ®µäºï¼åæ ·æ¯PyTupleObject对象ï¼å
æ¯ç±»åæ 示0x28ï¼ç¶å4个åè为é¿åº¦2.æ¥ç第ä¸ä¸ªå
ç´ æ¯None(N)ï¼å³0x4eï¼ç¶åæ¯ç¬¬äºä¸ªå
ç´ 3ï¼ç±»åæ 示æ¯TYPE_INT(i)ï¼å³0x69.åé¢4个åèæ¯æ´æ°3.
忥çå°±æ¯co_namesï¼åæ ·æ¯PyTupleObjectå¯¹è±¡ï¼æ¾ç¤ºæ 示0x28ï¼ç¶å4个åè为é¿åº¦1ï¼ç¶åå符sæ¯TYPE_INTERNEDç±»åï¼äºæ¯æ¥çæ¯æ 示't'ï¼å³0x74ï¼ç¶åæ¯å符å
容s(0x73)ã
æ¥ä¸æ¥æ¯co_varnamesï¼åæ ·æ¯PyTupleObjectï¼ç±»åæ¯0x28ï¼ç¶å4个åè为é¿åº¦1ï¼ç¶åæ¯å符aã
åå颿¯éå
ç¸å
³çä¸è¥¿co_freevarsï¼ä¸ºç©ºçPyTupleObjectï¼ç±»å0x28åé¢4个åèé¿åº¦ä¸º0.
ç¶åæ¯code blockå
é¨åµå¥å½æ°å¼ç¨çå±é¨åéåéåco_cellvarsï¼åæ ·æ¯ç©ºçPyTupleObject对象ã
æ¥ç0x73å¼å§å°±æ¯co_filenameäºï¼è¿æ¯PyStringObject对象ï¼å
æ¯å¯¹è±¡æ 示sï¼ç¶åæ¯é¿åº¦30.å颿¯å¯¹åºçæä»¶ç宿´è·¯å¾"/Users/ssj/Prog/python/test.py"ã
æ¥çæ¯co_nameï¼å³å½æ°åæè
ç±»åï¼è¿éå°±æ¯funcäºï¼é¦å
乿¯å¯¹è±¡æ 示't'(0x74)ï¼åé¢è·çé¿åº¦4ï¼ç¶åæ¯âfuncâè¿å个åèã
ç¶åæ¯co_firstlinenoï¼è¿éç´æ¥åçæ´æ°3.
ç¶åæ¯åèç æä»¤ä¸æºæä»¶è¡å·å¯¹åºå
³ç³»co_lnotabï¼ä»¥PyStringObject对象åå¨ãå
æ¯æ 示's'(0x73)ï¼ç¶åæ¯é¿åº¦4个åèï¼ç¶åæ¯å
容0x00010601.
好å§ï¼è³æ¤ï¼funcè¿ä¸ªcode objectåæå®æãæä»¬åå°å
¨å±çcode objectã
å
¨å±code objectä»co_consts[2]å¼å§,è¿æ¯Noneï¼å¦åé¢ä¸æ ·ï¼æ 示为0x4eãæ¥çå°±æ¯co_namesï¼co_varnamesçï¼åæè·åé¢funcç类似ï¼ä¸åèµè¿°ã注æçæ¯è¿éçco_names对åºç's'åâfunc'ç±»åä¸åæ¯TYPE_INTERNEDï¼èæ¯TYPE_STRINGREF('R'),弿¯0x52.è¿æå°±æ¯co_lnotabæ¯0x06020904ã
## 4.åèèµæ
- [Pythonç¨åºçæ§è¡åç](http://tech.uc.cn/?p=1932)(好æï¼ç²¾ç®å°ä½ï¼æä½äºéç¹)
- éåãPythonæºç åæã(å
容å¾å¤ï¼ææ¶é´å¼å¾æ
¢æ
¢ç ç©¶ç好书)