"symtable" --- 访问编译器的符号表
*********************************

**Source code：** Lib/symtable.py

======================================================================

符号表由编译器在生成字节码之前根据 AST 生成。符号表负责计算代码中每个
标识符的作用域。 "symtable" 提供了一个查看这些表的接口。


符号表的生成
============

symtable.symtable(code, filename, compile_type)

   返回 Python 源 *代码* 顶层的 "SymbolTable"。*filename* 是代码文件名
   。 *compile_type* 的含义类似 "compile()" 的 *mode* 参数。


符号表的查看
============

class symtable.SymbolTableType

   一个指明 "SymbolTable" 对象的类型的枚举。

   MODULE = "module"

      用于模块的符号表。

   FUNCTION = "function"

      用于函数的符号表。

   CLASS = "class"

      用于类的符号表。

   以下成员指向不同风格的 标注作用域。

   ANNOTATION = "annotation"

      当 "from __future__ import annotations" 被激活时用于标注。

   TYPE_ALIAS = "type alias"

      用于 "type" 构造的符号表。

   TYPE_PARAMETERS = "type parameters"

      用于 泛型函数 或 泛型类 的符号表。

   TYPE_VARIABLE = "type variable"

      用于正式意义下的绑定、约束元组或单个类型变量的默认值的符号变量的
      符号表，即 TypeVar, TypeVarTuple 或 ParamSpec 对象（后两者不支持
      绑定或约束元组）。

   Added in version 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_identifiers()

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

   lookup(name)

      在符号表中查找 *name* 并返回一个 "Symbol" 实例。

   get_symbols()

      返回符号表中所有符号的 "Symbol" 实例的列表。

   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"。


命令行用法
==========

Added in version 3.13.

"symtable" 模块可以在命令行下作为脚本来执行。

   python -m symtable [infile...]

符号表将针对指定的 Python 文件生成并转储至 stdout。 如果未指定输入文件
，将从 stdin 读取内容。
