python pyc === ###### tags: `python` # compile ```python= # [foo.py] def add(a, b): return a + b ``` ```python= # [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檔案的方法: ```python= # [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 ```