Python 零碎知识之高级版

wiki

1. __code__

1
2
3
def f():
pass
code = f.__code__

可以查看其属性 dir(f.__code__) ,其中有一些重要属性,如 ''co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_kwonlyargcount', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_posonlyargcount', 'co_stacksize', 'co_varnames'

1.1. co_code

使用二进制来保存这段代码的 byte code,类似汇编代码。可以使用 dis.dis(f) 来查看可读的 byte code。

1
print(code.co_code) # b'd\x00S\x00'

1.2. co_name, co_filename, co_lnotab

辅助数据,前者指函数名字,中间指函数在哪一个文件中被定义的,最后指用二进制代码表示的行号和 byte code 的一种关系,其中还包含 python 压缩算法,比较复杂

1
2
3
print(code.co_name)     # f
print(code.co_filename) # code_object.py
print(code.co_lnotab) # b'\x00\x01'

1.3. co_stacksize, co_flags

保存 python runtime 时 VM 数据,前者指占用空间,后者判断特别属性,如 *args, **kwargs 等,会根据其来生成不同的 byte code

1
2
print(code.co_stacksize) # 1
print(code.co_flags) # 67

1.4. co_argcount, co_posonlyargcount, co_kwonlyargcount

关于输入参数数量的,主要用于函数重载

1
2
3
print(code.co_argcount)         # 0
print(code.co_posonlyargcount) # 0
print(code.co_kwonlyargcount) # 0

1.5. co_nlocals, co_varnames, co_cellvars, co_freevars, co_names, co_consts

  • co_nlocals : 局部变量数量
  • co_varnames : 保存所有局部变量名
  • co_cellvars : 辅助闭包,此处变量可能在其他地方用到
  • co_freevars : 辅助闭包,此处变量是从其他地方来的
  • co_names : 存储局部变量、cellvars 和 freevars 外其他变量
  • co_consts : 存储用的的常量值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def f(a):
import math as m
b = a.attr
b = a.method()
b = "abc"
return b

code = f.__code__
print(code.co_nlocals) # 3
print(code.co_varnames) # ('a', 'm', 'b')
print(code.co_cellvars) # ()
print(code.co_freevars) # ()
print(code.co_names) # ('math', 'attr', 'method')
print(code.co_consts) # (None, 0, 'adc')