symtable — 访问编译器的符号表

源代码: Lib/symtable.py


符号表由编译器在生成字节码之前从 AST 生成。符号表负责计算代码中每个标识符的范围。symtable 提供了一个接口来检查这些表。

生成符号表

symtable.symtable(code, filename, compile_type)

返回 Python 源代码 code 的顶级 SymbolTablefilename 是包含代码的文件的名称。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_identifiers()

返回一个视图对象,其中包含表中符号的名称。请参阅 视图对象的文档

lookup(name)

在表中查找 name 并返回 Symbol 实例。

get_symbols()

返回表中名称的 Symbol 实例列表。

get_children()

返回嵌套符号表的列表。

symtable.函数

函数或方法的命名空间。此类继承自 SymbolTable

get_parameters()

返回包含此函数的参数名称的元组。

get_locals()

返回包含此函数中局部变量名称的元组。

get_globals()

返回包含此函数中全局变量名称的元组。

get_nonlocals()

返回包含此函数中非局部变量名称的元组。

get_frees()

返回包含此函数中自由变量名称的元组。

symtable.

类的命名空间。此类继承自 SymbolTable

get_methods()

返回包含类中声明的方法类函数的名称的元组。

此处,“方法”一词表示通过 defasync 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 仍被视为方法类函数。

symtable.符号

源代码中标识符对应的 SymbolTable 中的一个条目。构造函数不是公开的。

get_name()

返回符号的名称。

is_referenced()

如果符号在其块中使用,则返回 True

is_imported()

如果符号是从 import 语句创建的,则返回 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