"symtable" --- 存取編譯器的符號表
*********************************

**原始碼：**Lib/symtable.py

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

符號表 (symbol table) 是在生成位元組碼 (bytecode) 之前由編譯器從 AST
生成的。符號表負責計算程式碼中每個識別器 (identifier) 的範圍。
"symtable" 提供了一個介面來檢查這些表。


產生符號表
==========

symtable.symtable(code, filename, compile_type)

   回傳 Python 原始 *code* 的頂層 "SymbolTable"。*filename* 是包含程式
   碼之檔案之名稱。*compile_type* 類似於 "compile()" 的 *mode* 引數。


檢查符號表
==========

class symtable.SymbolTable

   一個區塊 (block) 的命名空間表 (namespace table) 。建構函式
   (constructor) 並不公開。

   get_type()

      回傳符號表的種類。可能的值為 "'class'"、"'module'"、"'function'"
      、"'annotation'"、"'TypeVar bound'"、"'type alias'" 和 "'type
      parameter'"。後四個是指不同的註釋範圍 (annotation scopes)。

      在 3.12 版的變更: 新增了 "'annotation'"、"'TypeVar bound'"、
      "'type alias'" 和 "'type parameter'" 作為可能的回傳值。

   get_id()

      回傳表的識別器。

   get_name()

      回傳表的名稱。如果表用於類別，則這是類別的名稱；如果表用於函式，
      則這是函式的名稱；如果表是全域的，則為 "'top'" （"get_type()" 會
      回傳 "'module'"）。對於型別參數作用域（用於泛型類別、函式和型別
      別名），它是底層類別、函式或型別別名的名稱。對於型別別名作用域，
      它是型別別名的名稱。對於 "TypeVar" 綁定範圍，它會是 "TypeVar" 的
      名稱。

   get_lineno()

      回傳此表所代表的區塊中第一行的編號。

   is_optimized()

      如果可以最佳化該表中的區域變數，則回傳 "True"。

   is_nested()

      如果區塊是巢狀類別或函式，則回傳 "True"。

   has_children()

      如果區塊內有巢狀命名空間，則回傳 "True"。這些可以通過
      "get_children()" 獲得。

   get_identifiers()

      回傳包含表中符號之名稱的視圖物件 (view object)。請參閱視圖物件的
      文件。

   lookup(name)

      在表中查找 *name* 並回傳一個 "Symbol" 實例。

   get_symbols()

      回傳表中名稱的 "Symbol" 實例串列。

   get_children()

      回傳巢狀符號表的串列。

class symtable.Function

   一個函式或方法的命名空間。該類別繼承自 "SymbolTable"。

   get_parameters()

      回傳一個包含此函式參數名稱的元組 (tuple)。

   get_locals()

      回傳一個包含此函式中區域變數 (locals) 名稱的元組。

   get_globals()

      回傳一個包含此函式中全域變數 (globals) 名稱的元組。

   get_nonlocals()

      回傳一個包含此函式中非區域變數 (nonlocals) 名稱的元組。

   get_frees()

      回傳一個包含此函式中自由變數 (free variables) 名稱的元組。

class symtable.Class

   一個類別的命名空間。該類別繼承自 "SymbolTable"。

   get_methods()

      回傳一個包含類別中聲明的類似方法之函式名稱的元組。

      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()[1]
      >>> 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()

      如果符號是從 import 陳述式建立的，則回傳 "True"。

   is_parameter()

      如果符號是一個參數，則回傳 "True"。

   is_global()

      如果符號是全域的，則回傳 "True"。

   is_nonlocal()

      如果符號是非區域的，則回傳 "True"。

   is_declared_global()

      如果使用全域陳述式將符號聲明為全域的，則回傳 "True"。

   is_local()

      如果符號是其區塊的區域符號，則回傳 "True"。

   is_annotated()

      如果符號有被註釋，則回傳 "True"。

      在 3.6 版被加入.

   is_free()

      如果該符號在其區塊中被參照 (referenced) 但未被賦值 (assigned)，
      則回傳 "True"。

   is_assigned()

      如果該符號被賦值到其區塊中，則回傳 "True"。

   is_namespace()

      如果名稱綁定引入 (introduce) 新的命名空間，則回傳 "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"。
