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

      Used for the symbol table of a module.

   FUNCTION = "function"

      Used for the symbol table of a function.

   CLASS = "class"

      Used for the symbol table of a class.

   The following members refer to different flavors of annotation
   scopes.

   ANNOTATION = "annotation"

      Used for annotations if "from __future__ import annotations" is
      active.

   TYPE_ALIAS = "type alias"

      Used for the symbol table of "type" constructions.

   TYPE_PARAMETERS = "type parameters"

      Used for the symbol table of generic functions or generic
      classes.

   TYPE_VARIABLE = "type variable"

      Used for the symbol table of the bound, the constraint tuple or
      the default value of a single type variable in the formal sense,
      i.e., a TypeVar, a TypeVarTuple or a ParamSpec object (the
      latter two do not support a bound or a constraint tuple).

   Added in version 3.13.

class symtable.SymbolTable

   某个代码块的命名空间表。构造函数不公开。

   get_type()

      Return the type of the symbol table.  Possible values are
      members of the "SymbolTableType" enumeration.

      在 3.12 版本发生变更: 增加 "'annotation'", "'TypeVar bound'",
      "'type alias'" 和 "'type parameter'" 作为可能的返回值。

      在 3.13 版本发生变更: Return values are members of the
      "SymbolTableType" enumeration.The exact values of the returned
      string may change in the future, and thus, it is recommended to
      use "SymbolTableType" members instead of hard-coded strings.

   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()

      Return a tuple containing the names of method-like functions
      declared in the class.

      Here, the term 'method' designates *any* function defined in the
      class body via "def" or "async def".

      Functions defined in a deeper scope (e.g., in an inner class)
      are not picked up by "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')

      Although "A().f()" raises "TypeError" at runtime, "A.f" is still
      considered as a method-like function.

class symtable.Symbol

   "SymbolTable" 中的数据项，对应于源码中的某个标识符。构造函数不公开
   。

   get_name()

      返回符号名

   is_referenced()

      如果符号在代码块中被引用了，则返回 "True"。

   is_imported()

      如果符号是由导入语句创建的，则返回 "True"。

   is_parameter()

      如果符号是参数，返回 "True"。

   is_type_parameter()

      Return "True" if the symbol is a type parameter.

      Added in version 3.14.

   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_free_class()

      Return *True* if a class-scoped symbol is free from the
      perspective of a method.

      Consider the following example:

         def f():
             x = 1  # function-scoped
             class C:
                 x = 2  # class-scoped
                 def method(self):
                     return x

      In this example, the class-scoped symbol "x" is considered to be
      free from the perspective of "C.method", thereby allowing the
      latter to return *1* at runtime and not *2*.

      Added in version 3.14.

   is_assigned()

      如果符号在代码块中赋值，则返回 "True"。

   is_comp_iter()

      Return "True" if the symbol is a comprehension iteration
      variable.

      Added in version 3.14.

   is_comp_cell()

      Return "True" if the symbol is a cell in an inlined
      comprehension.

      Added in version 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"。


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

Added in version 3.13.

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

   python -m symtable [infile...]

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