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
```