python pyc

tags: python

compile

# [foo.py] def add(a, b): return a + b
# [demo.py] import foo a = [1, 'python'] a = 'a string' def func(): a = 1 b = 257 print(a + b) print(a) if __name__ == '__main__': func() foo.add(1, 2)

python 在執行後會在目錄下產生pyc檔,在啟動python interpreter之後,python會將demo.py compile 成一個bytecode object PyCodeObject,在python中可以利用code object來檢視compile 後的bytecode object,這個PyCodeObject會在compile後被寫入在pyc中

建立pyc檔案的方法:

# [generate_pyc.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])
python generate_pyc.py [module.py]

如果要问 pyc 文件什么时候生成,答案就是在执行了 import 指令之后,from xx import yy 同样属于 import 指令。
compile 後的bytecode就會交給python virtual machine 執行

LEGB

python 使用LEGB規則來查找符號建立的對象(object)

locals -> enclosing function -> globals -> builtins

builtins,內建modules的命名空間。python在啟動時會載入很多的function、class,這些都位於__builtins__ modules之中,可以使用dir(__builtins__)來查看。

watch binary

 splasky  ~/workspace/python-virtual-machine-research/pyc_dump  1   hexdump -C __pycache__/ultra.cpython-37.pyc 
00000000  3e 0d 0d 0a 63 21 95 59  90 00 00 00 e3 00 00 00  |>...c!.Y........|
00000010  00 00 00 00 00 00 00 00  00 03 00 00 00 40 00 00  |.............@..|
00000020  00 73 1e 00 00 00 64 04  5c 02 5a 00 5a 01 65 00  |.s....d.\.Z.Z.e.|
00000030  73 10 65 01 72 1a 65 02  64 02 65 00 83 02 01 00  |s.e.r.e.d.e.....|
00000040  64 03 53 00 29 05 e9 01  00 00 00 e9 00 00 00 00  |d.S.)...........|
00000050  5a 05 48 65 6c 6c 6f 4e  29 02 72 01 00 00 00 72  |Z.HelloN).r....r|
00000060  02 00 00 00 29 03 da 01  61 da 01 62 da 05 70 72  |....)...a..b..pr|
00000070  69 6e 74 a9 00 72 06 00  00 00 72 06 00 00 00 fa  |int..r....r.....|
00000080  08 75 6c 74 72 61 2e 70  79 da 08 3c 6d 6f 64 75  |.ultra.py..<modu|
00000090  6c 65 3e 07 00 00 00 73  04 00 00 00 08 01 08 01  |le>....s........|
000000a0