symtable
--- 访问编译器的符号表¶
Source code: Lib/symtable.py
符号表由编译器在生成字节码之前根据 AST 生成。符号表负责计算代码中每个标识符的作用域。 symtable
提供了一个查看这些表的接口。
符号表的生成¶
- symtable.symtable(code, filename, compile_type)¶
返回 Python 源 代码 顶层的
SymbolTable
。filename 是代码文件名。 compile_type 的含义类似compile()
的 mode 参数。
符号表的查看¶
- class symtable.SymbolTable¶
某个代码块的命名空间表。构造函数不公开。
- get_type()¶
返回符号表的类型。 可能的值有
'class'
,'module'
,'function'
,'annotation'
,'TypeVar bound'
,'type alias'
和'type parameter'
。 后四种指的是不同形式的 标注作用域。在 3.12 版本发生变更: 增加
'annotation'
,'TypeVar bound'
,'type alias'
和'type parameter'
作为可能的返回值。
- get_id()¶
返回符号表的标识符
- get_name()¶
返回表名称。 如果表是针对类的则为类名;如果是针对函数的则为函数名;或者如果表是全局的 (
get_type()
返回'module'
) 则为'top'
。 对于类型形参作用域 (用于泛型类、函数和类型别名),它将为底层类、函数或类型别名的名称。 对于类型别名作用域,它将为类型别名的名称。 对于TypeVar
绑定作用域,它将为TypeVar
的名称。
- get_lineno()¶
返回符号表所代表代码块的第一行编号。
- is_optimized()¶
如果符号表中的局部变量可能被优化过,则返回
True
。
- is_nested()¶
如果代码块是嵌套类或函数,则返回
True
。
- has_children()¶
如果代码块中有嵌套的命名空间,则返回
True
。可通过get_children()
读取。
- get_children()¶
返回嵌套符号表的列表。
- class symtable.Function¶
函数或方法的命名空间。 该类继承自
SymbolTable
。- get_parameters()¶
返回由函数的参数名组成的元组。
- get_locals()¶
返回函数中局部变量名组成的元组。
- get_globals()¶
返回函数中全局变量名组成的元组。
- get_nonlocals()¶
返回函数中非局部变量名组成的元组。
- get_frees()¶
返回函数中自由变量名组成的元组。
- class symtable.Class¶
类的命名空间。 该类继承自
SymbolTable
。- get_methods()¶
返回一个包含类中声明的方法型函数的名称的元组。
在这里,术语 '方法' 是指 任何 在 class 语句体中通过
def
或async def
定义的函数。在更深的作用域(例如内部类)中定义的函数不会被
get_methods()
所获取。例如:
>>> import symtable >>> st = symtable.symtable(''' ... def outer(): pass ... ... class A: ... def f(): ... def w(): pass ... ... def g(self): pass ... ... @classmethod ... async def h(cls): pass ... ... global outer ... def outer(self): pass ... ''', 'test', 'exec') >>> class_A = st.get_children()[1] >>> class_A.get_methods() ('f', 'g', 'h')
虽然
A().f()
在运行时会引发TypeError
,但A.f
仍然被视为是方法型函数。
- class symtable.Symbol¶
SymbolTable
中的数据项,对应于源码中的某个标识符。构造函数不公开。- get_name()¶
返回符号名
- is_referenced()¶
如果符号在代码块中被引用了,则返回
True
。
- is_imported()¶
如果符号是由导入语句创建的,则返回
True
。
- is_parameter()¶
如果符号是参数,返回
True
。
- is_global()¶
如果符号是全局变量,则返回
True
。
- is_nonlocal()¶
如果符号为非局部变量,则返回
True
。
- is_declared_global()¶
如果符号用 global 声明为全局变量,则返回
True
。
- is_local()¶
如果符号是代码块内的局部变量,则返回
True
。
- is_annotated()¶
如果符号带有注解,则返回
True
。Added in version 3.6.
- is_free()¶
如果符号在代码块中被引用,但未赋值,则返回
True
。
- is_assigned()¶
如果符号在代码块中赋值,则返回
True
。
- is_namespace()¶
如果符号名绑定引入了新的命名空间,则返回
True
。如果符号名用于函数或类定义语句,则为 True。
例如:
>>> table = symtable.symtable("def some_func(): pass", "string", "exec") >>> table.lookup("some_func").is_namespace() True
注意,一个符号名可以与多个对象绑定。如果结果为
True
,则该符号名还可以绑定到其他对象上,比如 int 或 list ,且不会引入新的命名空间。
- get_namespaces()¶
返回与符号名绑定的命名空间的列表。
- get_namespace()¶
返回绑定到这个名称的命名空间。 如果有多个命名空间或没有命名空间被绑定到这个名称,则会引发
ValueError
。