symtable
— 访问编译器的符号表¶
源代码: Lib/symtable.py
符号表由编译器在生成字节码之前从 AST 生成。符号表负责计算代码中每个标识符的作用域。symtable
提供了一个接口来检查这些表。
生成符号表¶
- symtable.symtable(code, filename, compile_type)¶
返回 Python 源码 code 的顶级
SymbolTable
。filename 是包含代码的文件名。compile_type 类似于compile()
的 mode 参数。
检查符号表¶
- class symtable.SymbolTableType¶
一个枚举,指示
SymbolTable
对象的类型。- MODULE = "module"¶
用于模块的符号表。
- FUNCTION = "function"¶
用于函数的符号表。
- CLASS = "class"¶
用于类的符号表。
以下成员指的是不同类型的标注作用域。
- ANNOTATION = "annotation"¶
当
from __future__ import annotations
处于活动状态时,用于标注。
- TYPE_VARIABLE = "type variable"¶
用于表示正式意义上的单个类型变量(即 TypeVar、TypeVarTuple 或 ParamSpec 对象,后两者不支持边界或约束元组)的边界、约束元组或默认值的符号表。
在 3.13 版本加入。
- class symtable.SymbolTable¶
一个代码块的命名空间表。构造函数不公开。
- get_type()¶
返回符号表的类型。可能的值是
SymbolTableType
枚举的成员。3.12 版本中已更改: 添加了
'annotation'
、'TypeVar bound'
、'type alias'
和'type parameter'
作为可能的返回值。3.13 版本中已更改: 返回值是
SymbolTableType
枚举的成员。返回字符串的具体值将来可能会更改,因此建议使用
SymbolTableType
成员而不是硬编码的字符串。
- 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()¶
返回一个元组,其中包含此函数中显式声明的非局部变量名称。
- class symtable.Class¶
一个类的命名空间。此类继承自
SymbolTable
。- get_methods()¶
返回一个元组,其中包含在类中通过
def
或async def
声明的方法式函数的名称。在这里,“方法”一词指代通过
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()[2] >>> class_A.get_methods() ('f', 'g', 'h')
尽管
A().f()
在运行时会引发TypeError
,但A.f
仍然被认为是一个方法式函数。3.14 版本中已弃用,将在 3.16 版本中移除。
- class symtable.Symbol¶
SymbolTable
中的一个条目,对应于源中的一个标识符。构造函数不公开。- get_name()¶
返回符号的名称。
- is_referenced()¶
如果符号在其代码块中使用,则返回
True
。
- is_imported()¶
如果符号是由 import 语句创建的,则返回
True
。
- is_parameter()¶
如果符号是参数,则返回
True
。
- is_type_parameter()¶
如果符号是类型参数,则返回
True
。在 3.14 版本加入。
- is_global()¶
如果符号是全局的,则返回
True
。
- is_nonlocal()¶
如果符号是非局部变量,则返回
True
。
- is_declared_global()¶
如果符号用 global 语句声明为全局变量,则返回
True
。
- is_local()¶
如果符号是其代码块的局部变量,则返回
True
。
- is_annotated()¶
如果符号已被标注,则返回
True
。在 3.6 版本加入。
- is_free()¶
如果符号在其代码块中被引用但未被赋值,则返回
True
。
- is_free_class()¶
如果类作用域符号从方法的角度来看是自由的,则返回 True。
考虑以下示例
def f(): x = 1 # function-scoped class C: x = 2 # class-scoped def method(self): return x
在此示例中,类作用域符号
x
从C.method
的角度来看被认为是自由的,从而允许后者在运行时返回 1 而不是 2。在 3.14 版本加入。
- is_assigned()¶
如果符号在其代码块中被赋值,则返回
True
。
- is_comp_iter()¶
如果符号是推导式迭代变量,则返回
True
。在 3.14 版本加入。
- is_comp_cell()¶
如果符号是内联推导式中的一个单元格,则返回
True
。在 3.14 版本加入。
- 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
。
命令行用法¶
在 3.13 版本加入。
symtable
模块可以作为脚本从命令行执行。
python -m symtable [infile...]
为指定的 Python 源文件生成符号表并转储到标准输出。如果未指定输入文件,则从标准输入读取内容。