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
在类主体中定义的任何函数。在更深层次的作用域(例如,在内部类中)定义的函数不会被
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
。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
。
命令行用法¶
3.13 版本中新增。
可以从命令行将 symtable
模块作为脚本执行。
python -m symtable [infile...]
将为指定的 Python 源文件生成符号表,并将其转储到标准输出。 如果未指定输入文件,则从标准输入读取内容。